据说这题是要最小表示法做的,但我打算先朴素hash一波。
结果过了。。。
思路如下:
首先看题,发现是六元组,"6"确实不大。于是想到把雪花hash了。
对于hash值相同的一些雪花,用(O((num[hash]^2)*(6^2)))的时间复杂度来检查其中是否有符合条件的一组存在。(num[x]表示hash值为x的雪花共有num[x]个)
考虑hash值要取膜%p,为了更准确,于是把p取到n的附近。
然后,,,over。。。理论最大时间复杂度(O(n^2)),但实际上是达不到的。
代码:
//Copyright@3_soon,From Hangzhou No.2 High School Baimahu
//Problem:
//Result:
#include<bits/stdc++.h>
using namespace std;
#define re register
#define LL long long
#define DB double
#define il inline
#define For(x,a,b) for(re int x=a;x<=b;x++)
#define For2(x,a,b) for(re int x=a;x>=b;x--)
#define LFor(x,a,b) for(re LL x=a;x<=b;x++)
#define LFor2(x,a,b) for(re LL x=a;x>=b;x--)
#define Abs(x) ((x>0)? x:-x)
#define mod (LL)100003
int gi()
{
int res=0,fh=1;char ch=getchar();
while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
if(ch=='-') fh=-1,ch=getchar();
while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
return fh*res;
}
LL gl()
{
LL res=0,fh=1;char ch=getchar();
while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
if(ch=='-') fh=-1,ch=getchar();
while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
return fh*res;
}
int n;
int a[100005][7];
vector<int>p[100005];
LL sum;
il bool judge(int x,int y,int s)
{
int flag=1;
For(i,0,5) if(a[x][1+i]!=a[y][(s+i-1)%6+1]) {flag=0;break;}
if(flag) return 1;flag=1;
For(i,0,5) if(a[x][6-i]!=a[y][(s+i-1)%6+1]) {flag=0;break;}
if(flag) return 1;
return 0;
}
il bool check(int x,int s1)
{
For(i,0,p[x].size()-2)
For(j,1,6)
if(judge(s1,p[x][i],j)) return 1;
return 0;
}
int main()
{
n=gi();
For(i,1,n)
{
sum=0;
For(j,1,6) a[i][j]=gi(),sum+=a[i][j];
sum%=mod;
p[sum].push_back(i);
if(p[sum].size()>1&&check(sum,i)) {printf("Twin snowflakes found.
");return 0;}
}
printf("No two snowflakes are alike.
");
return 0;
}
2020.6.4 UPDATE
发现一种新的hash方式,欢迎来卡。
代码如下:
//Copyright@3_soon,From Hangzhou No.2 High School Baimahu
//Problem:
//Result:
#include<bits/stdc++.h>
using namespace std;
#define re register
#define LL long long
#define DB double
#define il inline
#define For(x,a,b) for(re int x=a;x<=b;x++)
#define For2(x,a,b) for(re int x=a;x>=b;x--)
#define LFor(x,a,b) for(re LL x=a;x<=b;x++)
#define LFor2(x,a,b) for(re LL x=a;x>=b;x--)
#define Abs(x) ((x>0)? x:-x)
#define mod (LL)100003
int gi()
{
int res=0,fh=1;char ch=getchar();
while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
if(ch=='-') fh=-1,ch=getchar();
while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
return fh*res;
}
LL gl()
{
LL res=0,fh=1;char ch=getchar();
while((ch>'9'||ch<'0')&&ch!='-') ch=getchar();
if(ch=='-') fh=-1,ch=getchar();
while(ch>='0'&&ch<='9')res=res*10+ch-'0',ch=getchar();
return fh*res;
}
int n;
int a[100005][7];
vector<int>p[100005];
LL sum,sum1;
il bool judge(int x,int y,int s)
{
int flag=1;
For(i,0,5) if(a[x][1+i]!=a[y][(s+i-1)%6+1]) {flag=0;break;}
if(flag) return 1;flag=1;
For(i,0,5) if(a[x][6-i]!=a[y][(s+i-1)%6+1]) {flag=0;break;}
if(flag) return 1;
return 0;
}
il bool check(int x,int s1)
{
For(i,0,p[x].size()-2)
For(j,1,6)
if(judge(s1,p[x][i],j)) return 1;
return 0;
}
int main()
{
// freopen("snowflakes1.in","r",stdin);
// freopen("snowflakes1.out","w",stdout);
n=gi();
For(i,1,n)
{
sum=0,sum1=1;
For(j,1,6) a[i][j]=gi(),sum=(sum+a[i][j])%mod,sum1=sum1*a[i][j]%mod;
sum=(sum+sum1)%mod;
p[sum].push_back(i);
if(p[sum].size()>1&&check(sum,i)) {printf("Twin snowflakes found.
");return 0;}
}
printf("No two snowflakes are alike.
");
return 0;
}