大意:给定雪花的六条边长,不论顺序,只要其中有两个雪花六条边的长度都相等,那么输出“Twin snowflakes found”,否则输出“No two snowflakes are alike.”

数据范围:0 < n ≤ 100000each integer is at least 0 and less than 10000000

思路:将每个状态映射进hash表里,由于不论顺序,我们可以在插入hash表的时候预排序一下,然后再映射进hash表里,如果找到,则标记。

注意:如果找到的话,不能直接退出循环,因为题目要求是全部输入完,否则一定会影响后面的结果(影响输入),这里我WA了一次。

CODE:

 

/*哈希函数*/
#include <iostream>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int MAXN  = 1000003;
const int N = 6;
typedef unsigned long UL;
typedef int State[6];

int first[MAXN], next[MAXN];
State st[MAXN], temp[MAXN];

char like[110] = "Twin snowflakes found.\n";
char unlike[110] = "No two snowflakes are alike.\n";

int n;
int flag;

inline void init()
{
    flag = 0;
    memset(first, -1sizeof(first));
}

inline int hash(State &s)
{
    UL v = 0;
    for(int i = 0; i < 6; i++) v =  v*10 + s[i];
    return v % MAXN;
}

inline int try_to_insert(int s)
{
    int h = hash(st[s]);
    for(int v = first[h]; v != -1; v = next[v])
    {
        if(memcmp(st[v], st[s], sizeof(st[s])) == 0return 0;
    }
    next[s] = first[h];
    first[h] = s;
    return 1;
}

void solve()
{
    for(int j = 0; j < N; j++) scanf("%d", &temp[0][j]);
    sort(temp[0], temp[0]+N);
    memcpy(st[0], temp[0], sizeof(temp[0]));
    try_to_insert(0);
    for(int i = 1; i < n; i++)
    {
        for(int j = 0; j < N; j++) scanf("%d", &temp[i][j]);
        sort(temp[i], temp[i]+N);
        memcpy(st[i], temp[i], sizeof(temp[i]));
        if(!try_to_insert(i))
        {
            flag = 1;
        }
    }
    printf("%s", flag? like:unlike); //found, not found.
}

int main()
{
    int i, j;
    while(~scanf("%d", &n))
    {
        init();
        solve();
    }
    return 0;
}

 

posted on 2012-11-05 15:44  有间博客  阅读(568)  评论(0编辑  收藏  举报