2020牛客暑期多校第八場G-Game SET(暴力假題)
阿新 • • 發佈:2020-08-03
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\)
\(T\leq 1000,n\leq 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*T\approx 6e7\)。。。。要\(O(1)\)查詢啊?我列舉一下四個性質都直接爆了。。。怎麼搞啊!!
後來講題的時候。。。。\(O(n^3)\)就可以直接過了,我????,實際上當n大於等於21的時候是一定有解的。。。當然,你也可以直接暴力模擬,我們這邊就有個大模擬選手寫了500來行的模擬過了。。。我是辣雞QAQ。。
至於證明過程。。。Here,實際上我並打不開的連結
那麼我們就可以直接暴力了。。。我們簡化一些判斷的條件,用string寫起來會方便很多那麼不合法的就是當兩個性質記為\(s1,s2\)
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\n",i+1,j+1,k+1);
mk=1; break;
}
}
if (mk) break;
}
if (mk) break;
}
if (!mk) printf("-1\n");
}
return 0;
}