题目大意:就是在给出的雪花当中判断有没有至少一样的一对雪花。
思路:在10W片雪花中直接比较雪花明显不可,但是经过哈希之后可以边插入边比较。
//Memory Time
//16696K 3766MS
#include<iostream>
using namespace std;
const __int64 prime=999983; // 10n内最大的素数(本题n=10W)
class
{
public:
__int64 len[6]; //6瓣叶子的长度
}leaf[100001];
typedef class HashTable
{
public:
__int64 len[6]; //记录6瓣叶子的长度信息
HashTable* next; //用于冲突时开放寻址
HashTable() //Initial
{
next=0;
}
}Hashtable;
Hashtable* hash[prime+1];//模拟链表的头指针的作用
/*计算第k个雪花的关键字key*/
__int64 compute_key(int k)
{
__int64 key=0;
for(int i=0;i<6;i++)
{
key+=(leaf[k].len[i]) % prime;
key%=prime; //利用同余模定理计算key,避免出现大数
}
return ++key; //键值后移1位,把key的范围从0~999982变为 1~999983
}
/*从顺时针方向判断两片雪花是否相同*/
bool clockwise(Hashtable* p,int k)
{
for(int j=0;j<6;j++) //顺时针转动j格
{
bool flag=true;
for(int i=0;i<6;i++)
if(leaf[k].len[i] != p->len[(i+j)%6])
{
flag=false;
break;
}
if(flag)
return true;
}
return false;
}
/*从逆时针方向判断两片雪花是否相同*/
bool counterclockwise(Hashtable* p,int k)
{
for(int j=0;j<6;j++) //逆时针转动j格
{
bool flag=true;
for(int i=0;i<6;i++)
if(leaf[k].len[i] != p->len[(5-i-j+6)%6])
{
flag=false;
break;
}
if(flag)
return true;
}
return false;
}
/*把第k个雪花信息插入HashTable*/
/*当插入的位置已存在其他雪花信息时,顺便比较*/
bool insert(int k)
{
__int64 key=compute_key(k);
if(!hash[key])
{
Hashtable* temp=new Hashtable;
for(int i=0;i<6;i++)
temp->len[i]=leaf[k].len[i];
hash[key]=temp; //保存key对应的地址
}
else //地址冲突,开放寻址,顺便比较
{
Hashtable* temp=hash[key];
if(clockwise(temp,k) || counterclockwise(temp,k)) //检查雪花是否相同
return true;
while(temp->next) //寻址
{
temp=temp->next;
if(clockwise(temp,k) || counterclockwise(temp,k)) //检查雪花是否相同
return true;
}
temp->next=new Hashtable; //申请空间,保存新雪花信息
for(int i=0;i<6;i++)
temp->next->len[i]=leaf[k].len[i];
}
return false;
}
int main(int i,int j)
{
int n; //雪花数
while(cin>>n)
{
/*Initial*/
memset(hash,0,sizeof(hash)); // 0 <-> NULL
/*Input*/
bool flag=false; //记录输入过程中是否出现了相同的雪花
for(i=1;i<=n;i++)
{
for(j=0;j<6;j++)
scanf("%I64d",&leaf[i].len[j]);
/*Hash*/
if(!flag) //当前还没有出现相同的雪花
flag=insert(i);
//若出现相同的雪花,则还需后续输入,但不再处理
}
/*Output*/
if(flag)
cout<<"Twin snowflakes found."<<endl;
else
cout<<"No two snowflakes are alike."<<endl;
}
return 0;
}
另转:http://axorb.diandian.com/post/2011-07-14/40029160561
#include<iostream>
#define M 99991
using namespace std;
struct Snow
{
long leg[7];
Snow * next;
}snow[M+5];
void shushi(void)
{
for(int i=0;i<M;i++)
{
memset(snow[i].leg,0,sizeof(snow[i].leg));
snow[i].next=NULL;
}
}
int Hash(long a[])
{
long long x=0;
x=a[0]+a[1]+a[2]+a[3]+a[4]+a[5];
return x%M;
}
int to_insert(long a[])
{
int k=Hash(a);
Snow * p = &snow[k];
while(p->next!=NULL)p=p->next;
p->next=new Snow;
for(int i=0;i<6;i++)
p->next->leg[i]=a[i];
p->next->next=NULL;
return 0;
}
int judge(long a[],long b[])
{
long c[7];
for(int i=0;i<6;i++)
c[i]=a[6-i-1];
for(int i=0;i<6;i++)
{
int n=0;
for(int j=0;j<=5;j++)
if(a[(j+i)%6]==b[j])
n++;
if(n==6)return 1;
}
for(int i=0;i<6;i++)
{
int n=0;
for(int j=0;j<=5;j++)
if(c[(j+i)%6]==b[j])
n++;
if(n==6)return 1;
}
return 0;
}
int main(){
long n,arm[7];
cin >> n;
int mark=0;
shushi();
while(n--)
{
for(int i=0;i<6;i++)
scanf("%ld",&arm[i]);
if(mark)continue;
int k=Hash(arm);
Snow * p=snow[k].next;
while(p!=NULL)
{
if(judge(p->leg,arm))
mark=1;
p=p->next;
}
to_insert(arm);
}
if(mark) printf("Twin snowflakes found.\n");
else printf("No two snowflakes are alike.\n");
system("pause");
}
#include<iostream>
#define M 99991
using namespace std;
struct Snow
{
long leg[7];
Snow * next;
}snow[M+5];
void shushi(void)
{
for(int i=0;i<M;i++)
{
memset(snow[i].leg,0,sizeof(snow[i].leg));
snow[i].next=NULL;
}
}
int Hash(long a[])
{
long long x=0;
x=a[0]+a[1]+a[2]+a[3]+a[4]+a[5];
return x%M;
}
int to_insert(long a[])
{
int k=Hash(a);
Snow * p = &snow[k];
while(p->next!=NULL)p=p->next;
p->next=new Snow;
for(int i=0;i<6;i++)
p->next->leg[i]=a[i];
p->next->next=NULL;
return 0;
}
int judge(long a[],long b[])
{
long c[7];
for(int i=0;i<6;i++)
c[i]=a[6-i-1];
for(int i=0;i<6;i++)
{
int n=0;
for(int j=0;j<=5;j++)
if(a[(j+i)%6]==b[j])
n++;
if(n==6)return 1;
}
for(int i=0;i<6;i++)
{
int n=0;
for(int j=0;j<=5;j++)
if(c[(j+i)%6]==b[j])
n++;
if(n==6)return 1;
}
return 0;
}
int main(){
long n,arm[7];
cin >> n;
int mark=0;
shushi();
while(n--)
{
for(int i=0;i<6;i++)
scanf("%ld",&arm[i]);
if(mark)continue;
int k=Hash(arm);
Snow * p=snow[k].next;
while(p!=NULL)
{
if(judge(p->leg,arm))
mark=1;
p=p->next;
}
to_insert(arm);
}
if(mark) printf("Twin snowflakes found.\n");
else printf("No two snowflakes are alike.\n");
system("pause");
}