题意:有一种牌,有四种属性(机翻尽是些奇奇怪怪的东西),每种属性又分为三种,但在这三种之上有一种是*,它可以代替其他三种。现给你n张牌,问能不能找到三张牌,它们的所有属性都相同或者所有属性都不同。
这题做法很简单,暴力枚举即可。虽然最坏的情况下(无解)时间复杂度乍看一下T*n3最大达到了6e9,但是当n>=21时必有解。至于证明过程。。放过我吧,能力有限,题解证明这个结论过程竟然是英文的,英语渣看不懂。
#include<iostream>
#include<string>
#include<algorithm>
#include<vector>
using namespace std;
string arr[400][5];
bool cmp(string s1,string s2,string s3) {//判断是否存在部分不相等
if (s1 == s2 && s2 != s3 && s1 != "*" && s3 != "*") return false;
if (s1 == s3 && s1 != s2 && s1 != "*" && s2 != "*") return false;
if (s2 == s3 && s1 != s2 && s1 != "*" && s2 != "*") return false;
return true;
}
bool solve(int i, int j, int k) {
for (int t = 1; t <= 4; t++){
if (!cmp(arr[i][t],arr[j][t],arr[k][t])) {
return false;
}
}
return true;
}
int main() {
ios::sync_with_stdio(false);
int t;
cin >> t;
for (int Case = 1; Case <= t; Case++) {
int n;
cin >> n;
for (int k = 1; k <= n; k++) {
string str;
cin >> str;
int top = 1;
int len = str.length();
for (int i = 0; i < len; i++) {//获取4个属性
while (str[i] != '[') i++;
int j = i + 1;
while (str[j] != ']') j++;
arr[k][top] = str.substr(i+1,j-i-1);
++top;
if (top > 4) break;
}
}
cout << "Case #" << Case << ": ";
bool sign = false;
for (int i = 1; i <= n; i++) {
for (int j = i + 1; j <= n; j++) {
for (int k = j + 1; k <= n; k++ ) {
if (solve(i, j, k)) {
cout << i << " " << j << " " << k << endl;
sign = true;
}
if (sign) break;
}
if (sign) break;
}
if (sign) break;
}
if (!sign) {
cout << "-1" << endl;
}
}
}