题目链接:
hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5183
bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=570&pid=1002
题解:
前缀和+哈希
维护两张哈希表hash1,hash2,一张维护前缀和sum=a[0]-a[1]+a[2]-a[3]+...+(-1)^i*a[i],另一张维护-sum=-a[0]+a[1]-a[2]+a[3]-...+(-1)^(i+1)*a[i];当i为奇数的时候,插入到第一张哈希表hash1,当i为偶数的时候插入到第二张表hash2,每次查询在hash1中是否存在sum-k,或在hash2中是否存在-sum-k,如果有一个条件成立,则说明有解。否则继续做下去,直到最后还没有答案则无解。
代码:
hash表大小设为100007,输入为int,用vector做hash,g++,1185MS高飘
1 #include<map> 2 #include<cstdio> 3 #include<vector> 4 #include<cstring> 5 #include<iostream> 6 #include<algorithm> 7 using namespace std; 8 9 typedef long long LL; 10 11 const int mod = 100007; 12 13 int n,k; 14 15 vector<LL> v[2][mod]; 16 17 int Hash(LL x) { 18 return (x%mod + mod) % mod; 19 } 20 21 bool que(LL x,int type) { 22 int key = Hash(x); 23 for (int i = 0; i < v[type][key].size(); i++) { 24 if (v[type][key][i] == x) return true; 25 } 26 return false; 27 } 28 29 void add(LL x,int type) { 30 int key = Hash(x); 31 if (!que(x,type)) { 32 v[type][key].push_back(x); 33 } 34 } 35 36 void init() { 37 for (int i = 0; i < mod; i++) { 38 v[0][i].clear(); 39 v[1][i].clear(); 40 } 41 } 42 43 int main() { 44 int tc, kase=0; 45 scanf("%d", &tc); 46 while (tc--) { 47 scanf("%d%d", &n, &k); 48 init(); 49 LL sum = 0; 50 bool ans = 0; 51 for (int i = 0; i < n; i++) { 52 int x; 53 scanf("%d", &x); 54 if (i & 1) sum -= x; 55 else sum += x; 56 if (que(sum - k,0) || que(-sum - k,1)) { 57 ans = true; 58 } 59 if (i & 1) add(sum, 0); 60 else add(-sum, 1); 61 } 62 if (sum == k) ans = true; 63 printf("Case #%d: ",++kase); 64 if (ans) printf("Yes.\n"); 65 else printf("No.\n"); 66 } 67 return 0; 68 }