HDU6344-调查问卷
调查问卷
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; }