C - Keys
https://atcoder.jp/contests/abc356/tasks/abc356_c
思路
对于样例1中的两种情况,可以推知如下推论:
(1)1 2为real keys
(2)1 3 为real keys,
(3)上面两个不能同为真。
更一般的情况,可以把测试用例分为 正测试样例 和 负测试样例
正测试样例, 测试key集中, 必须包含 real keys(至少K个), 还可能包含 dummy keys 。
负测试样例, 测试key集中 , 可能包含 dummy keys, 也可能包含 real keys(必须小于K个)。
对于任何一组钥匙的组合C(选择钥匙的一结果), 要保证跟 任何 正测试样例 和 负测试样例 都没有矛盾,
则必须要保证:
(1)任一正测试样例, 组合C跟此正测试样例的钥匙交集必须包含至少K个钥匙
(2)任一负测试样例, 组合C跟此正测试样例的钥匙交集必须包含不多于K个钥匙
Code
https://atcoder.jp/contests/abc356/submissions/54250649
int n,m,k;int main() {cin >> n >> m >> k;vector<int> a(m);vector<bool> r(m);for(int i=0; i<m; i++){int c;cin >> c;for(int j=0; j<c; j++){int key;cin >> key;key--;a[i] |= 1 << key;}char test;cin >> test;r[i] = test == 'o'? true : false;}// iterate all combinationsint maxc = 1 << n;int ans = 0;for(int i=0; i<maxc; i++){bool contradict = false;for(int j=0; j<m; j++){int overlap = i & a[j];// count 1 numberint keycnt = 0;while(overlap){if (overlap & 1){keycnt++;}overlap >>= 1;}if (r[j] && keycnt>=k){continue;}else if (!r[j] && keycnt<k){continue;}contradict = true;break;}if (!contradict){ans++;}}cout << ans << endl;return 0; }