poj_3349

来源:互联网 发布:淘宝评价怎么修改差评 编辑:程序博客网 时间:2024/06/07 18:33

源链接:http://poj.org/problem?id=3349

........感觉这种题目没怎么做过。不太会,参照了下。

是这样子的,题目意思就是给你n片六角的雪花,它可以旋转,问给你n个雪花中是否能找到两个相同形状的雪花。

其实思路还是比较清晰的,用哈希+开放式寻址即可。对于每一朵雪花,我们计算它的哈希值,然后看看看哈希表中是否存在该哈希值,如果不存在,那么将它放入该表;如果存在,那么就沿着那条哈希值相同的链一直找下去,直到找到末尾,如果还没有找到,那么就把当前的雪花放置到该链的末尾。

#include<stdio.h>#include<iostream>#include<string>#include<string.h>#include<algorithm>#include<iomanip>#include<vector>#include<time.h>#include<queue>#include<stack>#include<iterator>#include<math.h>#include<stdlib.h>#include<limits.h>#include<map>//#define ONLINE_JUDGE#define eps 1e-8#define INF 0x7fffffff#define FOR(i,a) for((i)=0;i<(a);(i)++)#define MEM(a) (memset((a),0,sizeof(a)))#define sfs(a) scanf("%s",a)#define sf(a) scanf("%d",&a)#define sfI(a) scanf("%I64d",&a)#define pf(a) printf("%d\n",a)#define pfI(a) printf("%I64d\n",a)#define pfs(a) printf("%s\n",a)#define sfd(a,b) scanf("%d%d",&a,&b)#define sft(a,b,c)scanf("%d%d%d",&a,&b,&c)#define for1(i,a,b) for(int i=(a);i<b;i++)#define for2(i,a,b) for(int i=(a);i<=b;i++)#define for3(i,a,b)for(int i=(b);i>=a;i--)#define MEM1(a) memset(a,0,sizeof(a))#define MEM2(a) memset(a,-1,sizeof(a))const double PI=acos(-1.0);template<class T> T gcd(T a,T b){return b?gcd(b,a%b):a;}template<class T> T lcm(T a,T b){return a/gcd(a,b)*b;}template<class T> inline T Min(T a,T b){return a<b?a:b;}template<class T> inline T Max(T a,T b){return a>b?a:b;}using namespace std;#define ll __int64int n,m;#define Mod 1000000007#define N 110#define M 1000100const int prime=999983;struct Leaf{int len[6];}leaf[M];struct Hashtable{//用hashtable作为开放式寻址int len[6];Hashtable *next;Hashtable(){next = 0;}};Hashtable *hash[prime+5];int getKey(int k){//得到一片雪花的哈希值int key = 0;for(int i=0;i<6;i++){key += (leaf[k].len[i])%prime;key %= prime;}//key++;return key;}bool clockwise(Hashtable *p,int k){//比较两片雪花按照顺时针顺序是否相同for(int j=0;j<6;j++){int flag = 1;for(int i=0;i<6;i++)if(leaf[k].len[i] != p->len[(i+j)%6])flag = 0;if(flag)return true;}return false;}bool counterclockwise(Hashtable *p,int k){//比较两片雪花按照逆时针顺序是否相同for(int j=0;j<6;j++){int flag = 1;for(int i=0;i<6;i++)if(leaf[k].len[i] != p->len[(5-i-j+6)%6])flag = 0;if(flag)return true;}return false;}bool insert(int k){//插入一片雪花int key = getKey(k);if(!hash[key]){//如果这个哈希值没有出现过Hashtable *tmp = new Hashtable;for(int i=0;i<6;i++)tmp->len[i] = leaf[k].len[i];hash[key] = tmp;//那么就把它放入hashtable中,并记录其地址}else{Hashtable *tmp = hash[key];//如果该哈希值出现过,那么先检查该哈希值的第一个雪花是否与该雪花相同if(clockwise(tmp,k) || counterclockwise(tmp,k))return true;while(tmp->next){//沿着那一个相同的哈希值链找下去tmp = tmp->next;if(clockwise(tmp,k) || counterclockwise(tmp,k))return true;}tmp->next = new Hashtable;//如果上面的还没找到,那么就把当前的雪花放入该链的末尾for(int i=0;i<6;i++)tmp->next->len[i] = leaf[k].len[i];}return false;}int main(){#ifndef ONLINE_JUDGE    freopen("in.txt","r",stdin);//  freopen("out.txt","w",stdout);#endif    while(sf(n)!=EOF){    memset(hash,0,sizeof hash);    int flag = 0;    for(int i=0;i<n;i++){    for(int j=0;j<6;j++)    scanf("%d",&leaf[i].len[j]);    if(!flag)    flag = insert(i);//    }    if(flag)    printf("Twin snowflakes found.\n");    else    printf("No two snowflakes are alike.\n");    }return 0;}


0 0