POJ---3274[Gold Balanced Lineup] 数组的hash

来源:互联网 发布:黄金太阳2通关数据 编辑:程序博客网 时间:2024/06/05 12:06

 

 

hash函数抄网上的,自己写的死活没过:

 

 

/*数组的hash*/
//思路:
//(1):sum[i][j]表示前i头牛第j个特征的总和
//(2):sum[b][j]-sum[a-1][j];表示[a,b]头牛第j个特征总和
//(3):sum[b][1]-sum[a-1][1]=....=sum[b][K]-sum[a-1][K];表示[a,b]这(b-a+1)头牛是平衡的
//(4):转换成:
//sum[b][1]-sum[b][2]=sum[a][1]-sum[a][1];
//sum[b][1]-sum[b][3]=sum[a][1]-sum[a][3];
//.......................................
//.......................................
//sum[b][1]-sum[b][K-1]=sum[a][1]-sum[a][K-1];
//sum[b][1]-sum[b][K]=sum[a][1]-sum[a][K];
//(5):令c[i][j]=sum[i][1]-sum[i][j];
//(6):则表示[a,b]这(b-a+1)头牛是平衡的可转换成判断c[a-1]=c[b]是否成立
//(7):这样我们就可以在求的c[i][j](1<=i<=N,1<=j<=K)的基础上,对数组c[i](1<=i<=N)hash,用开散列法(拉链法)求解即可.

 

CODE:

/*AC代码:235ms*/#include <iostream>#include <cstdio>#include <memory.h>#include <algorithm>#define max(a,b) (a>b?a:b)#define MOD 19997#define MAXN 100005using namespace std;int head[20000],next[MAXN];int N,K;int sum[MAXN][33],c[MAXN][33];int hash(int v[])//hash函数{int i,h=0;for(i=1;i<=K;i++)h=((h<<2)+(v[i]>>4))^(v[i]<<10);h%=MOD;h=h<0?h+MOD:h;return h;}void Init(){int i,j,temp;memset(sum,0,sizeof(sum));for(i=1;i<=N;i++){scanf("%d",&temp);for(j=1;j<=K;j++){sum[i][j]=sum[i-1][j]+temp%2;temp/=2;}for(j=1;j<=K;j++)c[i][j]=sum[i][1]-sum[i][j];}}void Solve(){int i,j,k,ans=0;memset(head,-1,sizeof(head));for(i=0;i<=N;i++)//注意这里从0开始{int h=hash(c[i]);//if(i==0)// printf("*%d %d\n",i,h);bool ok=false;for(j=head[h];j!=-1;j=next[j]){for(k=1;k<=K;k++){if(c[i][k]!=c[j][k]) break;}if(k>K)//find,因为每个都不同,所以不必再往下找了{ans=max(ans,i-j);//注意不能加一ok=true;break;}}if(!ok)//已经有相同的就不用再插入了{next[i]=head[h];head[h]=i;}}printf("%d\n",ans);}int main(){while(scanf("%d%d",&N,&K)!=EOF){Init();Solve();}return 0;}

 

原创粉丝点击