poj 3349 Snowflake Snow Snowflakes (简单题 hash)

来源:互联网 发布:mac 命令行 编辑:程序博客网 时间:2024/06/03 19:27

题目链接:http://poj.org/problem?id=3349

题意:给你一个六边形六条边的边长,给出的顺序可能是顺时针的也可能是逆时针的,给出的起点也是不一定的,找是否有两个六边形是一样的。

思路:比较水了,主要是解决一个问题,因为给出的顺序是可顺可逆的并且起点也是不一样的,怎么将六边形唯一表示出来?我一开始的想法是将边长最小的当成起点,然后分别枚举顺时针和逆时针两周表示方法,后来发现不行,因为最小边长可能用好多个,然后就用了更暴力的方法就是将12种表示方法全部都hash起来,加到vector里,然后就T了,十分无奈呀,后来就想到其实只需要将每个多边形最小的hash值压进vector里就好了~~。


code:

#include <cstdio>#include <cstdlib>#include <iostream>#include <vector>using namespace std;typedef unsigned long long ull;const int maxm=10007;const int maxn=100100;const ull B=9937;vector<ull> vv[maxm];pair<ull,int> pp[12];int a[6],c[6];int main(){    int n,pos,ta,dd;    bool flag,mark;    ull kk,rmin;    scanf("%d",&n);    for(int i=0;i<maxm;i++) vv[i].clear();    flag=false;    for(int i=0;i<n;i++){        for(int j=0;j<6;j++) scanf("%d",&a[j]);        for(int j=0;j<6;j++) c[j]=a[5-j];        rmin=-1;        for(int j=0;j<6;j++){            kk=0;            for(int k=j;k<6;k++) kk=kk*B+a[k];            for(int k=0;k<j;k++) kk=kk*B+a[k];            if(rmin==-1) rmin=kk;            else    rmin=min(rmin,kk);        }        for(int j=0;j<6;j++){            kk=0;            for(int k=j;k<6;k++) kk=kk*B+c[k];            for(int k=0;k<j;k++) kk=kk*B+c[k];            rmin=min(rmin,kk);        }        dd=rmin%maxm;        for(int j=0;j<vv[dd].size();j++){            if(rmin==vv[dd][j]){                flag=true;                break;            }        }        if(flag) break;        else vv[dd].push_back(rmin);    }    if(flag) printf("Twin snowflakes found.\n");    else printf("No two snowflakes are alike.\n");    return 0;}


0 0
原创粉丝点击