1. 程式人生 > >Snowflake Snow Snowflakes(POJ 3349)

Snowflake Snow Snowflakes(POJ 3349)

測評傳送門

題意:

給你n片雪花,每片雪花有六個角,每個角的形狀以一個數字表示(≤1e7),讓你判斷是否存在有兩片雪花一模一樣

判等當且僅當:

從任意一個角順時針或逆時針數字完全相符

若有,輸出:Twin snowflakes found.

若無,輸出:No two snowflakes are alike.

Sample Input

2
1 2 3 4 5 6
4 3 2 1 6 5

Sample Output

Twin snowflakes found.

思路:

最基本的 hip hop,H(snow) = 六個數字的乘積 + 六個數字的總和(應該不會衝突吧……)

每有一個 val 不同的雪花,我們通過鄰接表儲存

如果 val 相同了,我們再判斷順序是否相同,有些暴力,但好在資料小

就好啦~

Hash 注意開 long long 

code

#include<stdio.h> 
#include<string.h>
#include<algorithm> 
using namespace std;
const int P=99991,MXN=110000;
int n,cnt,next[MXN],head[MXN],snow[MXN][6];
int Hash(int *a) {
    int sum=0
,mul=1; for(int i=0;i<6;++i) { sum=(sum+a[i])%P; mul=(long long)mul*a[i]%P; } return (sum+mul)%P; } bool equ(int *a,int *b) { for(int i=0;i<6;++i) { for(int j=0;j<6;++j) { bool flag=1; for(int k=0;k<6;++k) {
if(a[(i+k)%6]!=b[(j+k)%6]) { flag=0;break; } } if(flag) return 1; flag=1; for(int k=0;k<6;++k) { if(a[(i+k)%6]!=b[(j-k+6)%6]) { flag=0;break; } } if(flag) return 1; } } return 0; } bool inser(int *a) { int val=Hash(a); for(int i=head[val];i;i=next[i]) { if(equ(a,snow[i])) return 1; } ++cnt; memcpy(snow[cnt],a,6*sizeof(int)); next[cnt]=head[val]; head[val]=cnt; return 0; } int main() { scanf("%d",&n); for(int i=1;i<=n;++i) { int t[6]; for(int i=0;i<6;++i) { scanf("%d",&t[i]); } if(inser(t)) { printf("Twin snowflakes found."); return 0; } } printf("No two snowflakes are alike."); return 0; }