第一次学习哈希,基本模仿题解写的
思路:首先这题时间比较紧,所以只能用加法求余来构造哈希表,然后容易出现冲突,所以冲突之后还需要判断是否为同种。
并且雪花有顺逆时针,所以需要两种时针方向,每种时针方向有6种情况都要讨论。
并且用链表把冲突的情况连到一起。
(感觉雪花有可能6个脚都一样长,那么同一种雪花的不同时针也会变成两种相同雪花?不知道题目里明确没,估计数据有点水)
#include <iostream>
#include <cstdio>
#include <cctype>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <cstring>
#include <string>
#include <vector>
#include <queue>
#include <map>
#include <set>
#include <sstream>
#include <stack>
using namespace std;
#define MAX 1200000+5
#define MAXN 100000+5
typedef long long LL;
typedef unsigned long long ull;
const double pi=3.141592653589793;
const int INF=0x3f3f3f3f;
const int INFF=1e9;
const double inf=1e18;
const double eps=1e-10;
const int mod=1000000007;
const int prime=999983;
struct node{
int num[6];
int next;
}snow[MAX];
int hashtable[prime];
int cur;
void init_hash(){
cur=0;
for(int i=0;i<prime;i++) hashtable[i]=-1;
}
unsigned int get_hash(int *num){
unsigned int _hash=0;
for(int i=0;i<6;i++){
_hash+=num[i];
}
return _hash%prime;
}
bool cmp(int *num1,int *num2){
for(int i=0;i<6;i++){
if(num1[i]!=num2[i]) return false;
}
return true;
}
void insert_hash(int *num,int h){
for(int i=0;i<6;i++) snow[cur].num[i]=num[i];
snow[cur].next=hashtable[h];
hashtable[h]=cur++;//同一个哈希值的情况构造个链表
}
bool search_hash(int *num){
int h=get_hash(num);
int next=hashtable[h];
while(next!=-1){
if(cmp(num,snow[next].num)) return true;
next=snow[next].next;//和同一个哈希值内的雪花作比较
}
insert_hash(num,h);
return false;
}
int main(){
int n;
scanf("%d",&n);
int num[2][15];
int flag=0;
init_hash();
while(n--){
for(int i=0;i<6;i++){
scanf("%d",&num[0][i]);
num[0][i+6]=num[0][i];//把6片叶子变成12个,便于寻找情况。
}
if(flag) continue;
for(int i=0;i<6;i++){
num[1][i]=num[1][i+6]=num[0][5-i];//换个时针方向
}
for(int i=0;i<6;i++){
if(search_hash(num[0]+i)||search_hash(num[1]+i)){//两种时针方向,6个开头都用哈希存。
flag=1;
break;
}
}
}
if(flag) printf("Twin snowflakes found.\n");
else printf("No two snowflakes are alike.\n");
return 0;
}