3的倍数(二进制枚举)

链接:https://ac.nowcoder.com/acm/contest/3282/D
来源:牛客网

给你 n个字符串,每个字符串最多包含 A−Z 这26个字母,Keven 现在取了一些字符串,发现每个字母出现的次数都是 3 的倍数,Keven 现在想要知道在满足每个字母出现的次数都是 3 的倍数的前提下,最多能取多少个字符串。

输入描述:

第一行一个数字 n,表示字符串的个数(1<=n<=15)

接下来 n 行,每行一个字符串 sss(1<=strlen(s)<=10000)

输出描述:

在一行中输出 Keven最多能取多少个字符串。

示例1

输入

复制
3
AB
AABBCCC
BB

输出

复制
2

说明

取第一个字符串和第二个字符串。


这个题一看到n只有15,一下想到二进制枚举
就是有个坑,如果你是在二进制枚举的时候遍历这个字符串的话,肯定会超时
但是你会发现和字符串没有关系,只和字符串里的26个字母有关
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=100;
int a[maxn][maxn];
int vis[maxn];
int main(){
    int n;
    cin>>n;
    string p;
    for(int i=0;i<n;i++){
        cin>>p;
        for(int j=0;j<p.size();j++){
            a[i][p[j]-'A']++;
        }
    }
    int ans=0;
    for(int i=0;i<(1<<n);i++){ 
        for(int j=0;j<26;j++){
            vis[j]=0;
        }
        int z=0;
        for(int j=0;j<n;j++){ 
            if((i>>j)&1){
                z++;
                for(int k=0;k<26;k++){
                    vis[k]+=a[j][k];
                }
            } 
        }
//        cout<<"d"<<i<<endl;
//        for(int j=0;j<26;j++){
//            cout<<vis[j]<<endl;
//        }
        int flag=1;
        if(z>ans){
            for(int j=0;j<26;j++){
                if(vis[j]%3!=0){
                    flag=0;
                    break;
                }
            }
            if(flag){
                ans=max(ans,z); 
            }
        }
    }
    cout<<ans<<endl;
}

 

 
posted @ 2021-01-13 00:02  哎呦哎(iui)  阅读(373)  评论(0编辑  收藏  举报