CSDN食用链接:https://blog.csdn.net/qq_43906000/article/details/107773134
题目大意:给你T组数据,每组n个字符串,你需要找出其中三个字符串使之能够构成一个集合,这个集合满足的条件为,对于字符串的每个性质,它要么全部一样,要么全部都不一样。如果不能找到输出-1,否则任意输出其位置。
字符串的构成如下:
([num][shape][shading ][color]),num性质包含(one,two,three),shape性质包含(diamond, squiggle,oval),shading的性质包含(solid, striped, open),color的性质包含(red, green, purple)
(Tleq 1000,nleq 256)
输入
3
3
[three][diamond][solid][red]
[two][*][solid][*]
[two][*][*][red]
5
[one][diamond][open][red]
[two][squiggle][solid][red]
[two][squiggle][*][red]
[two][diamond][solid][red]
[three][diamond][*][red]
6
[one][diamond][open][red]
[two][squiggle][*][green]
[two][squiggle][solid][green]
[two][diamond][solid][green]
[three][diamond][*][red]
[*][*][*][*]
输出
Case #1: -1
Case #2: 1 4 5
Case #3: 1 2 6
想的时候真的想用rand莽一发了,本来想用(n^2)的复杂的写的,结果我计算了一下,(n*n*Tapprox 6e7)。。。。要(O(1))查询啊?我枚举一下四个性质都直接爆了。。。怎么搞啊!!
后来讲题的时候。。。。(O(n^3))就可以直接过了,我????,实际上当n大于等于21的时候是一定有解的。。。当然,你也可以直接暴力模拟,我们这边就有个大模拟选手写了500来行的模拟过了。。。我是辣鸡QAQ。。
至于证明过程。。。Here,实际上我并打不开的链接
那么我们就可以直接暴力了。。。我们简化一些判断的条件,用string写起来会方便很多那么不合法的就是当两个性质记为(s1,s2),(s1=s2) 并且(s3!=s1,s3!="*",s1!="*") 即:
int no(string s1,string s2,string s3)
{
if (s1==s2 && s3!=s1 && s3!="*" && s1!="*") return 1;
if (s1==s3 && s2!=s1 && s2!="*" && s1!="*") return 1;
if (s2==s3 && s1!=s2 && s1!="*" && s2!="*") return 1;
return 0;
}
以下是AC代码:
#include <bits/stdc++.h>
using namespace std;
const int mac=1e3;
const int esp=1e3+10;
char s[mac][50];
int vis[300];
string ss[mac][6];
int no(string s1,string s2,string s3)
{
if (s1==s2 && s3!=s1 && s3!="*" && s1!="*") return 1;
if (s1==s3 && s2!=s1 && s2!="*" && s1!="*") return 1;
if (s2==s3 && s1!=s2 && s1!="*" && s2!="*") return 1;
return 0;
}
int ok(int id1,int id2,int id3)
{
int nb=0;
for (int i=1; i<=4; i++){
if (no(ss[id1][i],ss[id2][i],ss[id3][i])) return 0;
}
return 1;
}
int main(int argc, char const *argv[])
{
int t;
scanf ("%d",&t);
for (int cse=1; cse<=t; cse++){
int n;
scanf ("%d",&n);
for (int i=0; i<n; i++){
scanf ("%s",s[i]);
int len=strlen(s[i]);
int cnt=1;
ss[i][1]=ss[i][2]=ss[i][3]=ss[i][4]="";
for (int j=0; j<len; j++){
if (s[i][j]==']') {cnt++; continue;}
else if (s[i][j]=='[') continue;
ss[i][cnt]+=s[i][j];
}
}
int mk=0;
printf("Case #%d: ",cse);
for (int i=0; i<n-2; i++){
for (int j=i+1; j<n-1; j++){
for (int k=j+1; k<n; k++){
if (ok(i,j,k)){
printf("%d %d %d
",i+1,j+1,k+1);
mk=1; break;
}
}
if (mk) break;
}
if (mk) break;
}
if (!mk) printf("-1
");
}
return 0;
}