大意:给定雪花的六条边长,不论顺序,只要其中有两个雪花六条边的长度都相等,那么输出“Twin snowflakes found”,否则输出“No two snowflakes are alike.”
数据范围:0 < n ≤ 100000,each 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, - 1, sizeof(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])) == 0) return 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; }