• hdu 5183(Hash处理区间问题)


    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5183

    题意:给出一个n个元素的数组,现在要求判断 a1-a2+a3-a4+.....+/-an 中是否存在某个某个区间使得 ai-ai+1+ai+2...+(-1)j-iaj == k??

    这个题要利用Hash就可以实现几乎在 O(n) 的时间内实现查找判断.

    记录前缀和,然后枚举起点进行判断。分两种情况进行考虑:

    1.起点 i 为奇数,那么 a[i]-a[i+1]+a[i+2]....+(-1)^(j-i)*a[j] = sum[j] - sum[i-1] = k ,每次枚举 sum[i-1] + k 如果在hash表中存在 ,就证明存在此区间.

    2.起点 i 为偶数,那么 -a[i]+a[i+1]-a[i+2]....+(-1)^(j-i)*a[j] = sum[j] - sum[i-1] = -k ,每次枚举 sum[i-1] - k ,查找hash表。与上一步类似.

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <queue>
    #include <algorithm>
    #include <math.h>
    using namespace std;
    typedef long long LL;
    const int N = 1000005;
    const int H = 1000007;
    int Hash[H],cur;
    void initHash(){
        memset(Hash,-1,sizeof(Hash));
        cur = 0;
    }
    struct Node{
        LL v;
        int next;
    }node[N];
    void insertHash(LL v){
        int num = (int)(v%H+H)%H;
        node[cur].v = v;
        node[cur].next = Hash[num];
        Hash[num] = cur++;
    }
    bool searchHash(LL v){
        int num = (int)(v%H+H)%H;
        for(int k = Hash[num];k!=-1;k=node[k].next){
            if(node[k].v==v) return true;
        }
        return false;
    }
    LL sum[N];
    int main()
    {
        int tcase,t=1;
        scanf("%d",&tcase);
        while(tcase--){
            initHash();
            int n,k;
            scanf("%d%d",&n,&k);
            sum[0] = 0;
            for(int i=1;i<=n;i++){
                LL x;
                scanf("%lld",&x);
                if(i%2) sum[i] = sum[i-1]+x;
                else sum[i] = sum[i-1]-x;
            }
            insertHash(sum[n]);
            bool flag = false;
            for(int i=n;i>=1;i--){
                if(i%2==1&&searchHash(sum[i-1]+k)){
                    flag = true;
                    break;
                }
                if(i%2==0&&searchHash(sum[i-1]-k)){
                    flag = true;
                    break;
                }
                insertHash(sum[i]);
            }
            printf("Case #%d: ",t++);
            if(flag) printf("Yes.
    ");
            else printf("No.
    ");
        }
        return 0;
    }
  • 相关阅读:
    690. 员工的重要性
    91. 解码方法
    153. 寻找旋转排序数组中的最小值
    81. 搜索旋转排序数组 II
    33. 搜索旋转排序数组
    80. 删除有序数组中的重复项 II
    5708. 统计一个数组中好对子的数目
    高精度除法
    易闻app
    2021.4.13
  • 原文地址:https://www.cnblogs.com/liyinggang/p/5688444.html
Copyright © 2020-2023  润新知