今天闲来没事在poj上刷提,找找当年读本科的感觉。
随便选了个有关哈希的poj3349,题目比较简单,就是要找左循环或者右循环之后相等的序列。显然要先用hash进行预处理,刚开始用的是简单的6个长度之和进行哈希,后来这样做超时。后来加了个限制条件,即六个数之间的绝对和之差的和也要相等,这样就进一步减少了冲突。从这个小例子可以看出,哈希函数的设计对于提高效率还是有很大作用的。
PS:用cin进行数据的输入超时,scanf通过。
代码见下:
// snowflakes.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "iostream"
#include "vector"
using namespace std;
#define PRIME 220000
typedef struct node
{
long a[6];
}NODE;
vector<node> v[PRIME];
int judge(NODE tmp,int key)
{
int i;
vector<node>::iterator iter;
for(iter=v[key].begin();iter!=v[key].end();iter++)
{
if( tmp.a[0]==iter->a[0] && tmp.a[1]==iter->a[1] && tmp.a[2]==iter->a[2] &&
tmp.a[3]==iter->a[3] && tmp.a[4]==iter->a[4] && tmp.a[5]==iter->a[5] )
return 1;
else if( tmp.a[0]==iter->a[1] && tmp.a[1]==iter->a[2] && tmp.a[2]==iter->a[3] &&
tmp.a[3]==iter->a[4] && tmp.a[4]==iter->a[5] && tmp.a[5]==iter->a[0] )
return 1;
else if( tmp.a[0]==iter->a[2] && tmp.a[1]==iter->a[3] && tmp.a[2]==iter->a[4] &&
tmp.a[3]==iter->a[5] && tmp.a[4]==iter->a[0] && tmp.a[5]==iter->a[1] )
return 1;
else if( tmp.a[0]==iter->a[3] && tmp.a[1]==iter->a[4] && tmp.a[2]==iter->a[5] &&
tmp.a[3]==iter->a[0] && tmp.a[4]==iter->a[1] && tmp.a[5]==iter->a[2] )
return 1;
else if( tmp.a[0]==iter->a[4] && tmp.a[1]==iter->a[5] && tmp.a[2]==iter->a[0] &&
tmp.a[3]==iter->a[1] && tmp.a[4]==iter->a[2] && tmp.a[5]==iter->a[3] )
return 1;
else if( tmp.a[0]==iter->a[5] && tmp.a[1]==iter->a[0] && tmp.a[2]==iter->a[1] &&
tmp.a[3]==iter->a[2] && tmp.a[4]==iter->a[3] && tmp.a[5]==iter->a[4] )
return 1;
i=tmp.a[0];tmp.a[0]=tmp.a[5];tmp.a[5]=i;
i=tmp.a[1];tmp.a[1]=tmp.a[4];tmp.a[4]=i;
i=tmp.a[2];tmp.a[2]=tmp.a[3];tmp.a[3]=i;
if( tmp.a[0]==iter->a[0] && tmp.a[1]==iter->a[1] && tmp.a[2]==iter->a[2] &&
tmp.a[3]==iter->a[3] && tmp.a[4]==iter->a[4] && tmp.a[5]==iter->a[5] )
return 1;
else if( tmp.a[0]==iter->a[1] && tmp.a[1]==iter->a[2] && tmp.a[2]==iter->a[3] &&
tmp.a[3]==iter->a[4] && tmp.a[4]==iter->a[5] && tmp.a[5]==iter->a[0] )
return 1;
else if( tmp.a[0]==iter->a[2] && tmp.a[1]==iter->a[3] && tmp.a[2]==iter->a[4] &&
tmp.a[3]==iter->a[5] && tmp.a[4]==iter->a[0] && tmp.a[5]==iter->a[1] )
return 1;
else if( tmp.a[0]==iter->a[3] && tmp.a[1]==iter->a[4] && tmp.a[2]==iter->a[5] &&
tmp.a[3]==iter->a[0] && tmp.a[4]==iter->a[1] && tmp.a[5]==iter->a[2] )
return 1;
else if( tmp.a[0]==iter->a[4] && tmp.a[1]==iter->a[5] && tmp.a[2]==iter->a[0] &&
tmp.a[3]==iter->a[1] && tmp.a[4]==iter->a[2] && tmp.a[5]==iter->a[3] )
return 1;
else if( tmp.a[0]==iter->a[5] && tmp.a[1]==iter->a[0] && tmp.a[2]==iter->a[1] &&
tmp.a[3]==iter->a[2] && tmp.a[4]==iter->a[3] && tmp.a[5]==iter->a[4] )
return 1;
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
long i,n,key,sum;
int flag[PRIME]={0};
node tmp;
i=0;
cin >> n;
while(n--)
{
for(i=0,sum=0;i<6;i++)
{
//scanf("%ld",&tmp.a[i]);
cin >> tmp.a[i];
sum += tmp.a[i];
}
//hash
sum += abs(tmp.a[0]-tmp.a[1]) + abs(tmp.a[1]-tmp.a[2]) + abs(tmp.a[2]-tmp.a[3]) + abs(tmp.a[3]-tmp.a[4]) + abs(tmp.a[4]-tmp.a[5]) + abs(tmp.a[5]-tmp.a[0]);
key = sum%210011;
if(flag[key]==1)
{
if(judge(tmp,key)==1)
{
cout << "Twin snowflakes found.\n";
return 0;
}
}
else if(flag[key]==0)
flag[key]=1;
v[key].push_back(tmp);
}
cout << "No two snowflakes are alike.\n";
return 0;
}