题解 [SP4354][AcWing137]TWINSNOW - Snowflakes/雪花雪花雪花

Luogu link

洛谷的翻译不太清楚,这里是acwing题目链接:https://www.acwing.com/problem/content/139/

题解

算法:hash+邻接表+(最小表示法)

过程:

  • 读入雪花 a a a,进行 hash,得到一个值 h h h

  • 如果邻接表中有 hash 值为 h h h 的雪花,依次遍历这些雪花,与雪花 a a a 进行比较是否相同(可以使用暴力或最小表示法)

  • 如果相同输出 Twin snowflakes found.,否则继续读入

代码:

//SP4354
#include <cstring>
#include <cstdio>
typedef long long ll;
const int N=100010,P=99991;
int n,Snow[N][6],Head[N],Next[N],tot,a[10];

int Hash(int *a){
	// Hash 函数
	// Hash(a) = sum(i=1->6){a[i]}+mul(i=1->6){a[i]}
	int sum=0,mul=1;
	for(int i=0; i<6; ++i)
		sum=(sum+a[i])%P, mul=(ll)mul*a[i]%P;
	return (sum+mul)%P;
}
bool isequal(int *a,int *b){
	//判断两片雪花是否相等
	//暴力枚举两片雪花的“起始角”
	//判断一下,第二片翻过来再判断一下 
	for(int i=0; i<6; ++i){
		for(int j=0; j<6; ++j){
			
			bool yes=true;
			for(int k=0; k<6; ++k) if(a[(i+k)%6]!=b[(j+k)%6]) yes=false;
			if(yes) return true;
			
			yes=true;
			for(int k=0; k<6; ++k) if(a[(i+k)%6]!=b[(j-k+6)%6]) yes=false;
			if(yes) return true;
			
		}
	}
	return false;
}
bool findandinsert(int *a){
	//链式前向星邻接表 
	
	int h=Hash(a);
	for(int i=Head[h]; i; i=Next[i])
		if(isequal(Snow[i],a)) return true;
		
	++tot;
	memcpy(Snow[tot],a,6*sizeof(int));
	Next[tot]=Head[h],Head[h]=tot;
	
	return false;
}

int main(){
	scanf("%d",&n);
	for(int i=1; i<=n; ++i){
		for(int j=0; j<6; ++j)
			scanf("%d",&a[j]);
		if(findandinsert(a))
			return puts("Twin snowflakes found.")&0;
	}
	return puts("No two snowflakes are alike.")&0;
}
//qwq~~
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值