B - Gold Balanced Lineup解題報告(張浩盛倫)

CSUST_ACM發表於2012-03-21

B - Gold Balanced Lineup
Time Limit:2000MS     Memory Limit:65536KB     64bit IO Format:%I64d & %I64u

Description

Farmer John's N cows (1 ≤ N ≤ 100,000) share many similarities. In fact, FJ has been able to narrow down the list of features shared by his cows to a list of only K different features (1 ≤ K ≤ 30). For example, cows exhibiting feature #1 might have spots, cows exhibiting feature #2 might prefer C to Pascal, and so on.

FJ has even devised a concise way to describe each cow in terms of its "feature ID", a single K-bit integer whose binary representation tells us the set of features exhibited by the cow. As an example, suppose a cow has feature ID = 13. Since 13 written in binary is 1101, this means our cow exhibits features 1, 3, and 4 (reading right to left), but not feature 2. More generally, we find a 1 in the 2^(i-1) place if a cow exhibits feature i.

Always the sensitive fellow, FJ lined up cows 1..N in a long row and noticed that certain ranges of cows are somewhat "balanced" in terms of the features the exhibit. A contiguous range of cows i..j is balanced if each of the K possible features is exhibited by the same number of cows in the range. FJ is curious as to the size of the largest balanced range of cows. See if you can determine it.

Input

Line 1: Two space-separated integers, N and K
Lines 2..N+1: Line i+1 contains a single K-bit integer specifying the features present in cow i. The least-significant bit of this integer is 1 if the cow exhibits feature #1, and the most-significant bit is 1 if the cow exhibits feature #K.

Output

Line 1: A single integer giving the size of the largest contiguous balanced group of cows.

Sample Input

7 3
7
6
7
2
1
4
2

Sample Output

4

Hint

In the range from cow #3 to cow #6 (of size 4), each feature appears in exactly 2 cows in this range

題目連結:http://poj.org/problem?id=3274
解法型別:hash
解題思路:一道hash題啊,找key啊。當時做的時候覺得hash不好用,但它就是可以用hash優化,參考了一下別人的演算法,讓我對hash有了更深的領悟。首先把數轉化成二進位制矩陣,然後用一個陣列s[i][j]來儲存第j列的前i個數二進位制的和,再用一個陣列c[i][j]=s[i][j]-s[i][0],這樣,只要某兩行c[i][j]相同,那麼這兩行就可以算成一個contiguous balanced group。key就出來了,求和再取餘或相乘再取餘,隨你。。~
演算法實現:

//STATUS:C++_AC_969MS_27536K
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int MAXN=100010,MAX_HASH=99991;
int s[MAXN][30],c[MAXN][30];
int count(int a,int b);
int k;
struct NODE     //連結串列寫hash表
{
	struct NODE(){next=NULL;};
	int num;
	NODE *next;
}hash[MAX_HASH];
int main()
{
//	freopen("in.txt","r",stdin);
	int i,j,a,n,sumc,max;
	while(~scanf("%d%d",&n,&k))
	{
		max=0;
		memset(s,0,sizeof(s));
		memset(hash,0,sizeof(hash));
		NODE *p=(NODE*)malloc(sizeof(NODE));
		hash[0].num=0,hash[0].next=p,p->next=NULL;   //這個很重要,因為要考慮第一組的情況

		for(i=1;i<=n;i++){
		    scanf("%d",&a);
			for(j=0,sumc=0;j<k;j++){
		     	s[i][j]=s[i-1][j]+((a&(1<<j))?1:0);	   //位運算二進位制

				c[i][j]=s[i][j]-s[i][0];
				sumc+=c[i][j];
			}

			int t=sumc%MAX_HASH;
			if(t<0)t=-t;
			NODE *p=&hash[t];
			for(;p->next!=NULL;p=p->next){    //搜尋hash表
				int ok=count(p->num,i);
				if(ok!=-1 && ok>max)max=ok;
			}	
			NODE *q=(NODE*)malloc(sizeof(NODE));   //搜尋hash表
			p->num=i;
			p->next=q;
			q->next=NULL;
		}			
		printf("%d\n",max);
	}
	return 0;
}

int count(int a,int b)      //比較是否構成contiguous balanced group
{
	int j;
	for(j=0;j<k;j++){
		if(c[a][j]!=c[b][j])return -1;
	}
	return b-a;
}




相關文章