题目链接:Snowflake Snow Snowflakes
解题思路:这是关于雪花是否一样的题目,可以从顺时针逆时针来判定,设定不同的起始位置,最关键的是数据量比较大,要用hash表来做。哈希表简单来说就是数组和链表的结合体,在查找插入删除上面都有很好的时间复杂度。对于每一项数据,通过自定义的hash函数确定一个唯一的KEY值。再根据KEY值存放和查找数据。如果两个不同数据有相同的KEY值,那么就成为存在冲突,就可以用链表存储下所有相同KEY值的数据。这里采用的是所有数字相加取余数,Mod的是10W以内最大的素数。但我实验当素数变小时有时候时间会略微缩小,有时时间会略微变大。这可能与本身的测试数据有关。这里第一次交的时候用的是C++就超时了,用G++就刚刚好过。(vector还是比较慢)
#include<stdio.h>
#include<vector>
#define MAX 100000
#define FI 99991
using namespace std;
struct A{
int snow[6];
};
typedef struct A node;
vector<node> hash[MAX];
bool judge(int key, node a){
int i, j, k;
for(i = 0; i < hash[key].size(); i++){
int flag = 0;
for(j = 0; j < 6; j++){
for(k = 0; k < 6; k++){
if(a.snow[k] != hash[key][i].snow[(k + j) % 6]){
break;
}
}
if(k == 6) flag = 1;
for(k = 6; k > 0; k--){
if(a.snow[6 - k] != hash[key][i].snow[(k + j) % 6]){
break;
}
}
if(k == 0) flag = 1;
}
if(flag) return true;
}
return false;
}
int main(){
int i, j, k, n, key, flag;
node tem;
while(scanf("%d", &n) != EOF){
flag = 0;
for(i = 0; i < MAX; i++){
hash[i].clear();
}
for(i = 0; i < n; i++){
key = 0;
for(j = 0; j < 6; j++){
scanf("%d", &tem.snow[j]);
key = (key + tem.snow[j]) % FI;
}
if(!judge(key, tem)){
hash[key].push_back(tem);
}
else{
flag = 1;
}
}
if(flag){
printf("Twin snowflakes found.\n");
}
else{
printf("No two snowflakes are alike.\n");
}
}
return 0;
}