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 对问卷是不同的。
 

 

Input
第一行包含一个整数 T,表示有 T 组测试数据。

接下来依次描述 T 组测试数据。对于每组测试数据:

第一行包含三个整数 nm 和 k,含义同题目描述。

接下来 n 行,每行包含一个长度为 m 的只包含 'A' 和 'B' 的字符串,表示这份问卷对每个问题的回答。

保证 1T1001n10^31m101k10^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;
}

  

 

posted @ 2018-08-06 21:10  casccac  阅读(101)  评论(0编辑  收藏  举报