POJ 3349 Snowflake Snow Snowflakes

 

大意:给定雪花的六条边长,不论顺序,只要其中有两个雪花六条边的长度都相等,那么输出“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;
}

 

你可能感兴趣的:(poj)