poj 3274

解题思路看了官方的思路,就是前缀和的思想,做题时也想到了用前缀和,但没想到怎么才能提高效率,一点一点进步吧

做完后,各种失误,各种wa,经过n个时间的查错,终于ac啦

#include <iostream>
#include <cstdio>
using namespace std;
const int maxn=100000+3;
int s[maxn][35];
int a[maxn][35];
int head[maxn],nexvt[maxn];
int n,k;
int main()
{
	while(~scanf("%d%d",&n,&k))
	{
			int i,tem,j,p;
			memset(s,0,sizeof(s));
			memset(head,-1,sizeof(head));
			memset(a[0],0,sizeof(a[0]));
			nexvt[0]=head[0];//注意这两步,不要忽略第0条记录,因为区间内包括第1条记录,需要用到记录0,前缀和吗	
			head[0]=0;;
			int maxv=0;
			for(i=1;i<=n;i++)
			{
				scanf("%d",&tem);
				int key=0;
				for(j=0;j<k;j++)
				{
					s[i][j]=s[i-1][j]+((tem&(1<<j))>0?1:0);//这有错啦
					a[i][j]=s[i][j]-s[i][0];
					key=key+a[i][j]; 
				}
				if(key<0) key=-key;//注意此处key可能为负值。哎,思考的不严密啊,当一个值要作为数组下标,要注意啊
				key%=maxn;
				int loc=-1;
				for(j=head[key];j!=-1;j=nexvt[j])
				{
					for(p=0;p<k;p++)
					{
						if(a[i][p]!=a[j][p])
							break;
					}
					if(p==k&&i-j>maxv) maxv=i-j;//是i-j,不是i-j+1
				}
				nexvt[i]=head[key];
				head[key]=i;
			}
			printf("%d\n",maxv);
		}
		return 0;	
	}


posted @ 2013-03-16 11:05  LJ_COME!!!!!  阅读(230)  评论(0编辑  收藏  举报