XOJ3928: Snowflakes

据说这题是要最小表示法做的,但我打算先朴素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.\n");return 0;}
	}
	printf("No two snowflakes are alike.\n");
	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.\n");return 0;}
	}
	printf("No two snowflakes are alike.\n");
	return 0;
}
posted @ 2020-06-10 21:03  3_soon  阅读(132)  评论(0编辑  收藏  举报