题目大意:
给出n组数,每组六个数,这六个数环状,对于两组数从某位置顺时针或逆时针看这六个数若相同
如1 2 3 4 5 6和4 3 2 1 6 5 则代表相同的雪花
判断n组数是否完全不同
若没有相同的雪花输出
No two snowflakes are alike.
若有相同的输出
Twin snowflakes found.
/* 对于每一个雪花,都把它用最小表示法(字典序最小)表示 最后表示完后排序 这样如果相同的雪花就会被排到一块 看每个雪花是否和前一个相同 */ #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100010 using namespace std; int n,b[7],c[7],d[7]; struct node { int a[7]; }e[maxn]; int init() { int x=0,f=1; char c=getchar(); while(c<'0'||c>'9') { if(c=='-')f=-1; c=getchar(); } while(c>='0'&&c<='9') { x=x*10+c-'0'; c=getchar(); } return x*f; } int cmp(node x,node y) { for(int i=1;i<=6;i++) { if(x.a[i]==y.a[i])continue; return x.a[i]<y.a[i]; } return 0; } int can()//看是否是更小的字典序 { for(int i=1;i<=6;i++) { if(d[i]==c[i])continue; return c[i]<d[i]; } return 0; } void judge(int x)//找每组数的最小表示法 { int i,j,k; for(i=1;i<=6;i++) d[i]=b[i]; for(k=1;k<=6;k++) { int p=k; for(int l=1;l<=6;l++) { c[l]=b[p]; p++;if(p==7)p=1; } if(can()) for(j=1;j<=6;j++) d[j]=c[j]; } for(k=1;k<=6;k++) { int p=6-k+1; for(int l=1;l<=6;l++) { c[l]=b[p]; p--;if(p==0)p=6; } if(can()) for(j=1;j<=6;j++) d[j]=c[j]; } for(i=1;i<=6;i++) e[x].a[i]=d[i]; } int main() { int i,j,k; scanf("%d",&n); for(i=1;i<=n;i++) { for(j=1;j<=6;j++) b[j]=init(); judge(i); } sort(e+1,e+n+1,cmp);//排序 for(i=2;i<=n;i++) { int flag=0; for(j=1;j<=6;j++) if(e[i].a[j]!=e[i-1].a[j]) { flag=1; break; } if(flag==0)//有相同的 { printf("Twin snowflakes found. "); return 0; } } printf("No two snowflakes are alike. "); return 0; }