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;
}

猜你喜欢

转载自www.cnblogs.com/qseer/p/9812119.html