思路:以每组的和为key对每片雪花进行哈希,然后从和相等的雪花里进行匹配。
注意雪花的匹配顺序可以顺时针也可以逆时针
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 100001;//最大数量
const int MOD = 100000;//最大编号
struct snow{
int size[6];
snow(int arr[])//构造函数
{
for(int i=0;i<6;i++)
size[i] = arr[i];
}
};
vector<snow> ids[MAXN];//哈希
int arr[6];
int T;
bool issame(int arr1[],int arr2[])//判断是否相同
{
for(int i=0;i<6;i++)
{
if(arr1[0]==arr2[i%6] //顺时针顺序
&&arr1[1]==arr2[(i+1)%6]
&&arr1[2]==arr2[(i+2)%6]
&&arr1[3]==arr2[(i+3)%6]
&&arr1[4]==arr2[(i+4)%6]
&&arr1[5]==arr2[(i+5)%6]
)
return true;
if(arr1[0]==arr2[(i+5)%6] //逆时针顺序
&&arr1[1]==arr2[(i+4)%6]
&&arr1[2]==arr2[(i+3)%6]
&&arr1[3]==arr2[(i+2)%6]
&&arr1[4]==arr2[(i+1)%6]
&&arr1[5]==arr2[(i)%6]
)
return true;
}
return false;
}
void init() //容器初始化
{
for(int i=0;i<MAXN;i++)
{
if(!ids[i].empty())
ids[i].clear();
}
}
int main()
{
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
init();
while(n--) //读入n个值
{
int sum = 0;
for(int i=0;i<6;i++)
{
scanf("%d",&arr[i]);
sum += arr[i]; //用6个数值的和来给雪花编号
}
ids[sum%MOD].push_back(snow(arr));//把对应的雪花放入对应的编号里
}
bool hassame = false;//是否有相同的雪花
for(int i=0;i<=MOD;i++)
{
if(ids[i].size()>=2)//如果一个编号里有超过两个的雪花,说明他们有可能相同
{
for(int j=0;j<ids[i].size();j++)
{
for(int k=j+1;k<ids[i].size();k++)
{
if(issame(ids[i][j].size,ids[i][k].size))
{
hassame = true;
goto RETURN; //跳出循环
}
}
}
}
}
RETURN :
if(hassame)
printf("Twin snowflakes found.\n");
else
printf("No two snowflakes are alike.\n");
}
return 0;
}
奈何我冒泡的算法如何打动你超时的心!!!