世界上没有两片完全相同的雪花,本题要判断是否有两片雪花完全相同。
题中对雪花进行了简化,只是简单的将雪花的六个臂长作为数据,如果进一步根据分形学抽象雪花的话,那么题目的难度会有所增加。
由于数据的规模很大,所以如何比较两片雪花是关键。很自然的选择提取雪花的特征,所以应该根据六个臂长设计它的特征,该特征量设计的好坏是程序效率的主要因素。
本解法先简单的将各个臂长乘以一个系数并相加作为雪花的特征值,然后将该特征值作为散列值加入到表中,最后查找是否有相同的雪花存在。
#include <cstdio>
const int SNOWNUM = 100005;
const int HASHSIZE = 1000000;
struct staticList{
int data[6];
int next;
};
staticList sList[SNOWNUM];
int newNode;
int nHashIndex[HASHSIZE+5];
int main()
{
int i,j;
int num;
bool suc;
int tmp[6],data[6];
scanf("%d",&num);
for(i=0; i<num; ++i)
sList[i].next = -1;
for(i=0; i<HASHSIZE; ++i)
nHashIndex[i] = -1;
newNode = 0;
suc = false;
for(i=0; i<num; ++i)
{
int nClockSt = 0, nClockVa = 0, nClockVaTemp = 0;
int nCountSt = 0, nCountVa = 0, nCountVaTemp = 0;
for(j=0; j<6; ++j)
scanf("%d",&tmp[j]);
for(j=0; j<6; ++j)
{
nClockVaTemp = tmp[j] * 6 + tmp[(j+1)%6] * 5 + tmp[(j+2)%6] * 4 + tmp[(j+3)%6] * 3 + tmp[(j+4)%6] * 2 + tmp[(j+5)%6];
if(nClockVa < nClockVaTemp) {nClockVa = nClockVaTemp; nClockSt = j;}
nCountVaTemp = tmp[j] * 6 + tmp[(j+5)%6] * 5 + tmp[(j+4)%6] * 4 + tmp[(j+3)%6] * 3 + tmp[(j+2)%6] * 2 + tmp[(j+1)%6];
if(nCountVa < nCountVaTemp) {nCountVa = nCountVaTemp; nCountSt = j;}
}
if(nClockVa > nCountVa)
{
for(j=0; j<6; ++j)
data[j] = tmp[(nClockSt+j)%6];
}
else
{
for(j=0; j<6; ++j)
data[j] = tmp[(nCountSt+6-j)%6];
}
int nValue = nClockVa > nCountVa ? nClockVa : nCountVa;
nValue %= HASHSIZE;
if(nHashIndex[nValue] != -1)
{
int next = nHashIndex[nValue];
while(next != -1)
{
for(j=0; j<6; ++j)
if(data[j] != sList[next].data[j]) break;
if(j==6)
{
suc = true;
goto en;
}
next = sList[next].next;
}
for(j=0; j<6; ++j)
sList[newNode].data[j] = data[j];
sList[newNode].next = nHashIndex[nValue];
nHashIndex[nValue] = newNode;
++newNode;
}
else
{
for(j=0; j<6; ++j)
sList[newNode].data[j] = data[j];
nHashIndex[nValue] = newNode;
++newNode;
}
}
en: if(suc)
{
for(++i; i<num; ++i)
{
for(j=0; j<6; ++j)
scanf("%d",&tmp[j]);
}
}
if(suc)
printf("Twin snowflakes found.\n");
else
printf("No two snowflakes are alike.\n");
return 0;
}