调查问卷
Time Limit: 6500/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 169 Accepted Submission(s): 90
Problem Description
度度熊为了完成毕业论文,需要收集一些数据来支撑他的论据,于是设计了一份包含
m 个问题的调查问卷,每个问题只有 'A' 和 'B' 两种选项。
将问卷散发出去之后,度度熊收到了 n 份互不相同的问卷,在整理结果的时候,他发现可以只保留其中的一部分问题,使得这 n 份问卷仍然是互不相同的。这里认为两张问卷是不同的,当且仅当存在至少一个被保留的问题在这两份问卷中的回答不同。
现在度度熊想知道,存在多少个问题集合,使得这 n 份问卷在只保留这个集合的问题之后至少有 k 对问卷是不同的。
将问卷散发出去之后,度度熊收到了 n 份互不相同的问卷,在整理结果的时候,他发现可以只保留其中的一部分问题,使得这 n 份问卷仍然是互不相同的。这里认为两张问卷是不同的,当且仅当存在至少一个被保留的问题在这两份问卷中的回答不同。
现在度度熊想知道,存在多少个问题集合,使得这 n 份问卷在只保留这个集合的问题之后至少有 k 对问卷是不同的。
Input
第一行包含一个整数
T,表示有 T 组测试数据。
接下来依次描述 T 组测试数据。对于每组测试数据:
第一行包含三个整数 n,m 和 k,含义同题目描述。
接下来 n 行,每行包含一个长度为 m 的只包含 'A' 和 'B' 的字符串,表示这份问卷对每个问题的回答。
保证 1≤T≤100,1≤n≤10^3,1≤m≤10,1≤k≤10^6,给定的 n 份问卷互不相同。
接下来依次描述 T 组测试数据。对于每组测试数据:
第一行包含三个整数 n,m 和 k,含义同题目描述。
接下来 n 行,每行包含一个长度为 m 的只包含 'A' 和 'B' 的字符串,表示这份问卷对每个问题的回答。
保证 1≤T≤100,1≤n≤10^3,1≤m≤10,1≤k≤10^6,给定的 n 份问卷互不相同。
Output
对于每组测试数据,输出一行信息 "Case #x: y"(不含引号),其中 x 表示这是第
x 组测试数据,y 表示满足条件的问题集合的个数,行末不要有多余空格。
Sample Input
2
2 2 1
AA
BB
2 2 2
AA
BB
Sample Output
Case #1: 3
Case #2: 0
思路:每个问题只有AB两种答案,最多只有10个问题,所以可以将每份问卷转换成一个十位二进制数。同样因为最多10个问题,所以问题集合(wt)一共有1023(2^10-1)种,分别记为1-1023.
求问题集合的区分度:假设一个问题集合对应4种答案,那么区分度=(sum-A)*A+(sum-A-B)*B+(sum-A-B-C)*C+D*0
求每个问题集合答案种类,及每种答案个数:定义一个 int a[1024],置0,a[wt^b[i]]++;a[1024]++; //a[1024]就是sum
代码:
#include <stdio.h>
#include <iostream>
#include <algorithm>
#include <deque>
#include <string>
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0)
#define maxn 1009
#define maxk 1000009
using namespace std;
int t;
int m, n, k;
int biao_2[11]; //biao_2[i]0=2^i;
int wenjuan[maxn]; //以二进制形式存储每一份问卷
int ans[1028]; //纪录每个问题结合的区分度是否大于k,没有必要,单纯为了debug而设
string s;
int a[1028]; //纪录每个问题集合答案种类及其个数,使用前置0
void setbiao2() { //打表
biao_2[0] = 1;
for (int i = 1; i <= 10; i++) {
biao_2[i] = biao_2[i - 1] * 2;
}
}
int zhaobutong(int wt) { //求问题集合的区分度
int num = 0, sum = 0;
for (int i = 1; i <= n; i++) {
a[wenjuan[i] & wt]++;
sum++;
}
for (int i = 0; i <= biao_2[m]-1; i++) {
if (a[i]) {
sum -= a[i];
num += a[i] * sum;
a[i] = 0;
}
}
return num;
}
void solve() {
int butong,t;
for (int i = 1; i <= biao_2[m] - 1; i++) {
butong = zhaobutong(i);
if (butong >= k) {
ans[i]++; //没有必要,可以省略
ans[0]++;
}
}
}
int main() {
fio;
setbiao2();
cin >> t;
for(int i=1;i<=t;i++)
{
cin >> n >> m >> k;
memset(wenjuan, 0, sizeof wenjuan);
memset(a, 0, sizeof a);
memset(ans, 0, sizeof ans);
for (int i = 1; i <= n; i++) {
cin >> s;
for (int j = 0; j < m; j++) {
wenjuan[i] += biao_2[j]*(s[j] - 'A');
}
}
solve();
cout << "Case #" << i << ": " << ans[0] << endl;
}
return 0;
}