题意:给出n组序列, 每组序列6个数, 判断是否存在两个序列同构(即某个序列从某个位置起顺时针读出来的数与另外一个序列1-6的数一一对应)
解法: 具体看代码, 这题解得比较菜。。3000+ms。。。
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<vector>
using namespace std;
const int maxn = 100010;
bool flag=false;
int num[maxn][8];
vector<int>vec[maxn];
void deal(int v, int sum){
int i,j;
if(vec[sum].size() == 0) vec[sum].push_back(v); //当前key值对应的vector数组没有存储
else {//与之前输入的序列中key值与它相同的序列做比较
int len = vec[sum].size();
for(i=0; i<len; i++){
int p = vec[sum][i];
for(j=0; j<6; j++){ //顺时针
if(num[p][j%6] != num[v][0]) continue;
if(num[p][(j+1)%6] != num[v][1]) continue;
if(num[p][(j+2)%6] != num[v][2]) continue;
if(num[p][(j+3)%6] != num[v][3]) continue;
if(num[p][(j+4)%6] != num[v][4]) continue;
if(num[p][(j+5)%6] != num[v][5]) continue;
flag=true;
return ;
}
for(j=5; j>=0; j--){//逆时针
if(num[p][j%6] != num[v][0]) continue;
if(num[p][(j+5)%6] != num[v][1]) continue;
if(num[p][(j+4)%6] != num[v][2]) continue;
if(num[p][(j+3)%6] != num[v][3]) continue;
if(num[p][(j+2)%6] != num[v][4]) continue;
if(num[p][(j+1)%6] != num[v][5]) continue;
flag=true;
return ;
}
}
if(!flag) vec[sum].push_back(v);
}
return ;
}
int main()
{
int i, j, n;
memset(num, 0, sizeof(num));
scanf("%d", &n);
for(i=1;i<=n; i++){
int sum=0;
for(j=0; j<6; j++){
scanf("%d", &num[i][j]);
sum+=num[i][j];//将六个数字加起来作为key值
}
if(!flag) deal(i, sum%100007);
}
if(flag){
printf("Twin snowflakes found.\n");
} else {
printf("No two snowflakes are alike.\n");
}
return 0;
}