前言
这道题虽然是黄题,但其思维难度也不逊于一道蓝题,所以在AC后总结思路,写下此文。
思路
这道题的数据范围:
1
≤
T
≤
10
1 \le T \le 10
1≤T≤10,
1
≤
N
≤
100
1\le N \le100
1≤N≤100,
1
≤
M
≤
100
1 \le M \le 100
1≤M≤100
这样的数据范围支持时间复杂度
Θ
(
T
N
2
M
)
\varTheta(TN^2M)
Θ(TN2M)的枚举做法。
可以发现,Elsie写的代码都是类似于
if(b[i] == 0/1) return 0/1;
else if(b[j] == 0/1) return 0/1;
...
else return 0/1;
的判断结构
我们可以从
1
1
1到
N
N
N进行枚举,对于还未return的字符串进行判断。
若发现这些字符串的第
i
(
1
≤
i
≤
N
)
i(1 \le i \le N)
i(1≤i≤N)位上,为
0
0
0的或
1
1
1的都有一样的返回结果,则可以构造出一个判断语句。并把符合这个判断语句的字符串return
然而,这些判断语句不一定按照
i
i
i顺序排列,则最多枚举
N
N
N轮,就可以把所有的判断语句构造出来。
代码
for(int i = 0;i < t;i ++){
int n,m;
string s[100];
bool res[100],del[100];
bool ans = true;
memset(del,false,sizeof(del));
cin >> n >> m;
for(int j = 0;j < m;j ++){
cin >> s[j] >> res[j];
}
for(int j = 0;j < n;j ++){
for(int k = 0;k < n;k ++){
int ans[2] = {-1,-1};
bool have_ans[2];
memset(have_ans,true,sizeof(have_ans));
for(int l = 0;l < m;l ++){
if(del[l] == true) continue;
if(ans[s[l][k] - '0'] == -1) ans[s[l][k] - '0'] = res[l];
else if(ans[s[l][k] - '0'] != res[l]) have_ans[s[l][k] - '0'] = false;
}
for(int l = 0;l < m;l ++){
if(del[l] == true) continue;
else if(have_ans[s[l][k] - '0'] == true) del[l] = true;
}
}
}
for(int j = 0;j < m;j ++){
if(del[j] == false) ans = false;
}
if(ans == true) cout << "OK\n";
else cout << "LIE\n";
}