题意:n个数列 每个数列6个元素a[i],a[i]<=1e7,两个数列只要,经过若干次循环移动能相等则定义为相似.
n<=1e5,问n个数列中 是否存在两个数列相似?
每个数列只有6个数,则相似的最多12种,对每个数列算出其hash值 相同hash值插入同一个链表中.
查看新输入的数列插入时是否产生冲突即可 O(n*12)
#include <iostream> #include <cstdio> #include <cstring> #include <cmath> using namespace std; typedef long long ll; typedef pair<int,int> ii; const ll mod=1200007; const ll inf=1e18; const int N=2e6+20; int head[N],ip; void init() { memset(head,-1,sizeof(head)); ip=0; } struct node{ int num[6]; int next; }e[N]; int get_hash(int *num)//hash?μ { int h=0; for(int i=0;i<6;i++) h+=num[i]; return h%mod; } void insert_hash(int *num,int h) { for(int i=0;i<6;i++) e[ip].num[i]=num[i]; e[ip].next=head[h]; head[h]=ip++; } bool compare(int *a,int *b) { for(int i=0;i<6;i++) { if(a[i]!=b[i]) return false; } return true; } bool search_hash(int *num) { int h=get_hash(num); for(int i=head[h];i!=-1;i=e[i].next) { if(compare(num,e[i].num)) return true; } insert_hash(num,h); return false; } int main() { init(); int n,num[2][15]; bool flag=false; scanf("%d",&n); while(n--) { for(int i=0;i<6;i++) scanf("%d",&num[0][i]),num[0][i+6]=num[0][i];//clockwisze if(flag) continue; for(int i=0;i<6;i++) num[1][i]=num[1][i+6]=num[0][5-i]; for(int i=0;i<6;i++)//ê?·?ó?2úéú3?í? { if(search_hash(num[0]+i)||search_hash(num[1]+i)) { flag=true; break; } } } if(flag) printf("Twin snowflakes found.\n"); else printf("No two snowflakes are alike.\n"); return 0; }
时间: 2024-11-10 10:47:05