POJ3349_Snowflakes

原来看到过字符串hash

这次碰到了一个数值型hash就在比赛的时候放弃了,果然还是太弱,需要多学习


暴力的话,n平方的算法,而且需要顺时针和逆时针判断12次,肯定TLE

暴力不行才会需要想别的方法:

对所有的值进行HASH是分了对值进行分类,分类最正常也是最一般的想法就是%一个质数

质数选择很重要:几万左右的比较好


如果在一组的话,那么就使用暴力匹配,顺时针和逆时针判断12次,如果至少有1次匹配成功就说明正确

否则,当所有数据读完之后都没有,那就是没有结果


#include<map>
#include<set>
#include<math.h>
#include<time.h>
#include<iostream>
#include<cstdio>
#include<queue>
#include<stack>
#include<stdio.h>
#include<cstring>
#include<string.h>
#include<algorithm>
#include<cstdlib>
using namespace std;

#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define ll rt<<1
#define rr rt<<1|1
#define LL long long
#define ULL unsigned long long
#define maxnum 1000050
#define eps 1e-6
#define input freopen("input.txt","r",stdin)
#define output freopen("output.txt","w",stdout)

const int maxn=15000;
const int maxm=50;

struct node{
	int a[6];
}snow[maxn][maxm];

int m[maxn];

int hash(node x){
	int key=0;
	for(int i=0;i<6;i++)
		key+=x.a[i];
	key%=14997;
	return key;
}

int cmp(node x,node y){
	int st,i,j;
	for(st=0;st<6;st++){
		for(i=st,j=0;j<6;j++,i=(i+1)%6)
			if (x.a[i]!=y.a[j])  break;
		if (j==6) return 1;
		for(i=st,j=0;j<6;j++,i=(i+5)%6)
			if (x.a[i]!=y.a[j])  break;
		if (j==6) return 1;
	}
	return 0;
}

int main(){
	//input;
	int i,j,pos,n;
	node SNOW;
	scanf("%d",&n);
	memset(m,0,sizeof(m));
	for(i=1;i<=n;i++){
		for(j=0;j<6;j++) scanf("%d",&SNOW.a[j]);
		pos=hash(SNOW);
		for(j=0;j<m[pos];j++){
			if (cmp(SNOW,snow[pos][j])){
				puts("Twin snowflakes found.");
				return 0;
			}
		}
		snow[pos][m[pos]]=SNOW;
		m[pos]++;
	}
	puts("No two snowflakes are alike.");
	return 0;
}

只要存在一组马上就可以退出返回,不需要继续查询了

你可能感兴趣的:(ACM)