调查问卷(2018"百度之星"程序设计大赛 - 资格赛 )状态压缩

 

调查问卷

Time Limit: 6500/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)
Total Submission(s): 356    Accepted Submission(s): 182


 

Problem Description

度度熊为了完成毕业论文,需要收集一些数据来支撑他的论据,于是设计了一份包含 m 个问题的调查问卷,每个问题只有 'A' 和 'B' 两种选项。

将问卷散发出去之后,度度熊收到了 n 份互不相同的问卷,在整理结果的时候,他发现可以只保留其中的一部分问题,使得这 n 份问卷仍然是互不相同的。这里认为两张问卷是不同的,当且仅当存在至少一个被保留的问题在这两份问卷中的回答不同。

现在度度熊想知道,存在多少个问题集合,使得这 n 份问卷在只保留这个集合的问题之后至少有 k 对问卷是不同的。

 

 

Input

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

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

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

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

保证 1≤T≤100 ,1≤n≤103 ,1≤m≤10 ,1≤k≤106 ,给定的 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

 

 

Source

2018"百度之星"程序设计大赛 - 资格赛

#include <stdio.h>
#include <cstring>
#include <math.h>
#include <string>
#include <queue>
#include <map>
#include <stdlib.h>
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN=1e5+70;
const int MAX=1e9+7;
char s[1005][15];
int a[1005];
int tmp[1005];
int n,m,k;
void Change()//利用a[]保存s转换的01串
{
    for(int i=0;i<n;i++)
    {
        a[i]=0;
        for(int j=0;j<m;j++)
        {
            a[i]=(a[i]<<1)|(s[i][j]-'A');//此时应该把a[i]看成0000串 再移位或s串 得s串
        }
    }
}
int solve()
{
    cin>>n>>m>>k;
    for(int i=0;i<n;i++)
    {
        cin>>s[i];
    }
    Change();
    int sum=0;
    for(int i=1;i<(1<<m);i++)
    {
        for(int j=0;j<n;j++)
        {
            tmp[j]=a[j]&i;// tmp保存选第i位的试卷的结果(此时不考虑其他问卷,无影响)如i=2 a[j]=1101 ,1101&0010=0 而当a[j]=1110时 
        }//a[i]&i=1  当a[j]=1111时a[j]&i=i -->2 结果数字相同时表明问卷相同
        sort(tmp+0,tmp+n);// 此时在把tmp sort一下让相同的问卷在一起比如结果为001122则让他们相互不同匹配得不同问卷份
        int ans=0;
        int now=0;
        for(int j=0;j<n;j++)
        {
            if(tmp[j]!=tmp[now])
            {
                ans+=(j-now)*(n-j);
                now=j;
            }
        }
        if(ans>=k)
            sum++;
    }
    return sum;
    //cout<<sum<<endl;
}
int main()
{
    ios::sync_with_stdio(false);
        /*
        abababa
        abababa
        abababa
        abababb
        1100111
        1010010
        1001010
        0010010

        a[0]=0000->0001
        a[0]=0010->0011
        a[0]=0110->0110
        a[0]=1100->1100

        1234567*/
        int t;
        cin>>t;
        int t1=0;
        while(t--)
        {
            t1++;
            int res=solve();
            cout<<"Case #"<<t1<<": "<<res<<endl;

            //res++;
            //solve();
        }


    return 0;
}

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值