gym101612 Consonant Fencity

题意:给你一个长度为n的字符串,可以选择一些字符改变为大写,使得满足条件的字符对最多(条件为要求两个字符一个大写一个小写,并且不为元音yuan),问改变后的字符串

题解:首先发现题目规定不是元音的很少,小到可以位运算。。。其实就是直接暴力,枚举那些字符变为大写,这里复杂度(1<<19),1e6计算答案是不可能的,这里的点很少,只要建图直接19*19计算答案,所以最后的复杂度为19*19*(1<<19)

#include <bits/stdc++.h>
#define maxn 1010000
#define INF 0x3f3f3f3f
typedef long long ll;
using namespace std;
int G[300][300], f[300], dir[300], mk[300], mx, ans;
char s[maxn];
int main(){
    //freopen("consonant.in", "r", stdin);reopen("consonant.out", "w", stdout);
    f['a']=f['e']=f['i']=f['o']=f['u']=f['y']=f['w']=1;
    int num = 0;
    for(int i='a';i<='z';i++){
        if(f[i] != 1) dir[i] = num++;
    }
    scanf("%s",s+1);
    int l=strlen(s+1);
    for(int i=1; i<l; ++i){
        G[s[i]][s[i+1]]++;
        G[s[i+1]][s[i]]++;
    }
    for(int st=0; st<(1<<19); ++st){
        int c=0, ma=0;
        for(int i=0; i<19; ++i){
            if(st&(1<<i)) c++;
        }
        if(c>9) continue;
        for(int i='a'+1; i<='z'; ++i){
            if(f[i]) continue;
            int u=dir[i];
            for(int j='a'+1; j<='z'; ++j){
                if(f[j]) continue;
                int v=dir[j];
                if(((st>>u)&1) != ((st>>v)&1)) ma+=G[i][j];
            }
        }
        if(ma > mx) mx=ma, ans=st;
    }
    for(int i='a'; i<='z'; ++i){
        int u = dir[i];
        if(ans&(1<<u)) mk[i]=1;
    }
    for(int i=1; i<=l; ++i){
        if(mk[s[i]]) printf("%c",s[i]-32);
        else printf("%c",s[i]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/Noevon/p/7868244.html