这题直接两个for循环直接TLE,所以这里要先进行一次哈希,然后一次排序,这样只要比较相邻的并且hash值相同的两个串即可。
代码如下:
#include <cstdlib> #include <cstring> #include <cstdio> #include <algorithm> #define MOD 100000007 using namespace std; int N, a[6]; struct Node { int a[6], sum; bool operator < (Node t) const { return sum < t.sum; } }num[200010]; void cpto(int a[], int t[], int x) { for (int i = x, j = 0; j < 6; ++j, ++i) { t[j] = a[i%6]; } } bool OK(int a, int b) { int t[6], flag, rec[6]; for (int i = 0; i < 6; ++i) { // 依次将这些位放在第一位 flag = 1; cpto(num[a].a, t, i); for (int i = 0; i < 6; ++i) { if (t[i] != num[b].a[i]) { flag = 0; break; } } if (flag) { return true; } } for (int i = 5, j = 0; i >= 0; --i, ++j) { rec[j] = num[a].a[i]; } for (int i = 0; i < 6; ++i) { flag = 1; cpto(rec, t, i); for (int i = 0; i < 6; ++i) { if (num[b].a[i] != t[i]) { flag = 0; break; } } if (flag) { return true; } } return false; } int main() { int flag; while (scanf("%d", &N) == 1) { flag = 0; for (int i = 0; i < N; i++) { scanf("%d %d %d %d %d %d", a, a+1, a+2, a+3, a+4, a+5); memcpy(num[i].a, a, sizeof (a)); num[i].sum = 0; for (int j = 0; j < 6; ++j) { num[i].sum ^= a[j]; } num[i].sum %= MOD; } sort(num, num+N); for (int i = 0; i < N && !flag; ++i) { for (int j = i + 1; j < N; ++j) { if (num[i].sum != num[j].sum) { break; } if (OK(i, j)) { flag = 1; printf("Twin snowflakes found.\n"); break; } } } if (!flag) { puts("No two snowflakes are alike."); } } return 0; }