题意:给你一个长度为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; }