给出N个六边形的6个边长,问其中是否有完全相同的两个六边形,完全相同包括边的长度和位置都要相同。边给出的顺序是逆时针或者顺时针的。
给每个6边形一个哈希值,方法是对6条边长度的平方和取模
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 1e6; const int mod = 999983;//100W以内的大素数 typedef long long LL; int n; char s[100010][10]; int hash[maxn],next[maxn]; bool judge(int a,int b) { int i,j,k; for(i = 0; i < 6; ++i)//串的起始位置 { for(j = i,k = 0; k < 6; ++k,j = (j+1)%6)//顺时针 if(s[a][k] != s[b][j]) break; if(k == 6) return true; for(j = i,k = 0; k < 6; ++k, j = (j+5)%6)//逆时针 if(s[a][k] != s[b][j]) break; if(k == 6) return true; } return false; } int main() { //freopen("in","r",stdin); scanf("%d",&n); bool flag = false; for(int i = 1; i <= n; ++i) { int x = 0,u; for(int j = 0; j < 6; ++j) { scanf("%d",&s[i][j]); x = (int)((x+(LL)s[i][j]*(LL)s[i][j])%mod);//防止溢出 } u = hash[x];//hash【】里面存的是哈希值对应的某一行的行号 while(u){ if(judge(i,u)) {flag = true;break;}//只要u!=0,说明之前出现过这个hash值,则可能出现相同的六边形,判断一下 u = next[u];//沿着“链表”往下走 } if(flag)break; next[i] = hash[x];//类似链表的插入方法,把hash值相同的放在一起,方便以后用next可以遍历到所有hash相同的边 hash[x] = i;//更新表头 } if(flag) printf("Twin snowflakes found.\n"); else printf("No two snowflakes are alike.\n"); }
时间: 2024-11-06 22:40:58