标签:
http://bestcoder.hdu.edu.cn/contests/contest_showproblem.php?pid=1002&cid=570
给定一个数组(a0,a1,a2,?an−1)和一个整数K, 请来判断一下是否存在二元组(i,j)(0≤i≤j<n)使得 NP−sum(i,j) 刚好为K。这里NP−sum(i,j)=ai−ai+1+ai+2+?+(−1)^(j−i)*aj。
分基数和偶数讨论
开始用set做tle
后来改成哈希表+输入优化就好多了
线性探测和二次探测都大约800ms
线性探测法:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; #define ll long long #define mo 1000007 int a[1000010]; ll sum[1000010]; int n,k; ll v[1000010]; int n1[1000010],h[mo],ee; void ins(ll k) { int p=abs(k)%mo; v[ee]=k; n1[ee]=h[p]; h[p]=ee++; } bool find(ll k) { int p=abs(k)%mo; for(int i=h[p];~i;i=n1[i]) { if(v[i]==k)return true; } return false; } void clearh() { memset(h,-1,sizeof(h)); ee=0; } bool check() { clearh(); ins(0); for(int i=1;i<=n;i++) { if(i%2==0)ins(sum[i]); if(find(sum[i]-k))return true; } clearh(); //ou for(int i=1;i<=n;i++) { sum[i]=-sum[i]; if(i%2==1)ins(sum[i]); if(find(sum[i]-k))return true; } return false; } int getint() { int ret=0;bool ok=0,neg=0; for(;;) { int c=getchar(); if(c>=‘0‘&&c<=‘9‘)ret=(ret<<3)+ret+ret+c-‘0‘,ok=1; else if(ok)return neg?-ret:ret; else if(c==‘-‘)neg=1; } } int main() { int T; T=getint(); for(int cas=1;cas<=T;cas++) { n=getint(); k=getint(); for(int i=1;i<=n;i++)a[i]=getint(); for(int i=1;i<=n;i++){ if(i%2==1)sum[i]=sum[i-1]+a[i]; else sum[i]=sum[i-1]-a[i]; } printf("Case #%d: ",cas); if(check())puts("Yes."); else puts("No."); } return 0; }
二次探测法:
#include<iostream> #include<cstdio> #include<cmath> #include<cstring> using namespace std; #define ll long long #define mo 1000007 #define inf 2147000000 int a[1000010]; ll sum[1000010]; int n,k; ll h[mo]; void ins(ll k) { // return abs(k)%mo; ll p=abs(k),pp; for(int i=1;i<=n;i++) { pp=(p+i*i)%mo; if(h[pp]==inf){ h[pp]=k; return; } pp=((p-i*i)%mo+mo)%mo; if(h[pp]==inf){ h[pp]=k; return; } } } bool find(ll k) { ll p=abs(k),pp; for(int i=1;i<=n;i++) { pp=(p+i*i)%mo; if(h[pp]==inf)return 0; if(h[pp]==k){ return 1; } pp=((p-i*i)%mo+mo)%mo; if(h[pp]==inf)return 0; if(h[pp]==k){ return 1; } } return 0; } void clearh() { for(int i=0;i<mo;i++)h[i]=inf; } bool check() { clearh(); ins(0); //ji for(int i=1;i<=n;i++) { if(i%2==0)ins(sum[i]); if(find(sum[i]-k))return true; } clearh(); //ou for(int i=1;i<=n;i++) { sum[i]=-sum[i]; if(i%2==1)ins(sum[i]); if(find(sum[i]-k))return true; } return false; } int getint() { int ret=0;bool ok=0,neg=0; for(;;) { int c=getchar(); if(c>=‘0‘&&c<=‘9‘)ret=(ret<<3)+ret+ret+c-‘0‘,ok=1; else if(ok)return neg?-ret:ret; else if(c==‘-‘)neg=1; } } int main() { int T; T=getint(); for(int cas=1;cas<=T;cas++) { n=getint(); k=getint(); for(int i=1;i<=n;i++)a[i]=getint(); for(int i=1;i<=n;i++){ if(i%2==1)sum[i]=sum[i-1]+a[i]; else sum[i]=sum[i-1]-a[i]; } printf("Case #%d: ",cas); if(check())puts("Yes."); else puts("No."); } return 0; }
标签:
原文地址:http://www.cnblogs.com/kylehz/p/4322644.html