题目链接:http://poj.org/problem?id=3349
题意:给出n个雪花,判断是否存在两个雪花相似。
这道题数据有点问题,不考虑同构就可以过
比如这组数据:
2
1 2 3 4 5 6
3 1 2 4 5 6
我也是后来看到discuss才发现的。另外还要考虑到顺时针的逆时针的问题,一片雪花应该有12中序列表示方式。
后来参考discuss的代码做了修改。
正确的代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int H=1200007;
const int maxn=1200010;
int n,cnt;
struct node{
int num[6];
int next;
};
node p[maxn];
int Hash[maxn];
void init(){
cnt=0;
memset(Hash,-1,sizeof(Hash));
}
bool cmp(int *a,int *b){
for(int i=0;i<6;i++){
if(a[i]!=b[i])
return false;
}
return true;
}
int getHash(int *a){
int hash=0;
for(int i=0;i<6;i++)
hash+=a[i];
return hash%H;
}
void addHash(int *a,int hashNum){
for(int i=0;i<6;i++){
p[cnt].num[i]=a[i];
}
p[cnt].next=Hash[hashNum];
Hash[hashNum]=cnt;
cnt++;
}
bool searchHash(int *a){
int hashNum=getHash(a);
int next=Hash[hashNum];
for(int i=next;i!=-1;i=p[i].next){
if(cmp(a,p[i].num))
return true;
}
addHash(a,hashNum);
return false;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
while(~scanf("%d",&n)){
init();
bool flag=false;
for(int i=0;i<n;i++){
int tmp[2][12];
for(int j=0;j<6;j++){
scanf("%d",&tmp[0][j]);
tmp[0][j+6]=tmp[0][j];
}
for(int j=0;j<6;j++){
tmp[1][j]=tmp[1][j+6]=tmp[0][5-j];
}
if(!flag){
for(int j=0;j<6;j++){
if(searchHash(tmp[0]+j)||searchHash(tmp[1]+j)){
flag=true;
break;
}
}
}
}
if(flag) puts("Twin snowflakes found.");
else puts("No two snowflakes are alike.");
}
return 0;
}
附上错误的代码(未考虑同构,但依然可以AC):
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
using namespace std;
const int INF=0x3f3f3f3f;
const int H=14997;
const int maxn=15000;
int n;
struct node{
int num[10];
};
node p[maxn][100];
int m[maxn];
bool cmp(node a,node b){
sort(a.num,a.num+6);
sort(b.num,b.num+6);
for(int i=0;i<6;i++){
if(a.num[i]!=b.num[i])
return false;
}
return true;
}
int getHash(node a){
int hash=0;
for(int i=0;i<6;i++)
hash+=a.num[i];
return hash%H;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
while(~scanf("%d",&n)){
memset(m,0,sizeof(m));
bool flag=false;
for(int i=0;i<n;i++){
node tmp;
for(int j=0;j<6;j++){
scanf("%d",&tmp.num[j]);
}
if(!flag){
int hashNum=getHash(tmp);
for(int j=0;j<m[hashNum];j++){
if(cmp(tmp,p[hashNum][j])){
flag=true;
break;
}
}
p[hashNum][m[hashNum]++]=tmp;
}
}
if(flag) puts("Twin snowflakes found.");
else puts("No two snowflakes are alike.");
}
return 0;
}

该博客讨论了POJ 3349题目的解决策略,重点在于如何处理数据中的同构情况以及雪花旋转的12种表示。博主提到了原始数据可能存在错误,并分享了错误和修正后的代码。
&spm=1001.2101.3001.5002&articleId=50586359&d=1&t=3&u=99b0a2dd1c7a435aa526fb022e163af3)
464

被折叠的 条评论
为什么被折叠?



