Consonant Fencity
时间限制: 3 Sec 内存限制: 512 MB提交: 100 解决: 15
[ 提交][ 状态][ 讨论版][命题人: admin]
题目描述
There are two kinds of sounds in spoken languages: vowels and consonants. Vowel is a sound, produced with an open vocal tract; and consonant is pronounced in such a way that the breath is at least partly obstructed. For example, letters a and o are used to express vowel sounds, while letters b and p are the consonants (e.g. bad, pot).
Some letters can be used to express both vowel and consonant sounds: for example, y may be used as a vowel (e.g. silly) or as a consonant (e.g. yellow). The letter w, usually used as a consonant (e.g. wet) could produce a vowel after another vowel (e.g. growth) in English, and in some languages (e.g. Welsh) it could be even the only vowel in a word.
In this task, we consider y and w as vowels, so there are seven vowels in English alphabet: a, e, i, o, u, w and y, all other letters are consonants.
Let's define the consonant fencity of a string as the number of pairs of consecutive letters in the string which both are consonants and have different cases (lowercase letter followed by uppercase or vice versa). For example, the consonant fencity of a string CoNsoNaNts is 2, the consonant fencity of a string dEsTrUcTiOn is 3 and the consonant fencity of string StRenGtH is 5.
You will be given a string consisting of lowercase English letters. Your task is to change the case of some letters in such a way that all equal letters will be of the same case (that means, no letter can occur in resulting string as both lowercase and uppercase), and the consonant fencity of resulting string is maximal.
Some letters can be used to express both vowel and consonant sounds: for example, y may be used as a vowel (e.g. silly) or as a consonant (e.g. yellow). The letter w, usually used as a consonant (e.g. wet) could produce a vowel after another vowel (e.g. growth) in English, and in some languages (e.g. Welsh) it could be even the only vowel in a word.
In this task, we consider y and w as vowels, so there are seven vowels in English alphabet: a, e, i, o, u, w and y, all other letters are consonants.
Let's define the consonant fencity of a string as the number of pairs of consecutive letters in the string which both are consonants and have different cases (lowercase letter followed by uppercase or vice versa). For example, the consonant fencity of a string CoNsoNaNts is 2, the consonant fencity of a string dEsTrUcTiOn is 3 and the consonant fencity of string StRenGtH is 5.
You will be given a string consisting of lowercase English letters. Your task is to change the case of some letters in such a way that all equal letters will be of the same case (that means, no letter can occur in resulting string as both lowercase and uppercase), and the consonant fencity of resulting string is maximal.
输入
The only line of the input contains non-empty original string consisting of no more than 106 lowercase English letters.
输出
Output the only line: the input string changed to have maximum consonant fencity.
样例输入
consonants
样例输出
coNsoNaNts
题意是给定你一串字符,分为元音字母和辅音字母,将辅音字母变成大写,要构成尽量多的大写字母和小写字母的组合,最后输出改变后的字符串。
由于辅音字母的数量才19个,少到可以状态压缩,将相邻点建边,边权为1,这样可以将字符串转化为1个图,相邻字符的出现次数可以表现为图的权值,这样去枚举每一种状态,然后内层去找每一步状态得到的权值,当权值最大时,保留状态,最后将所有状态为1的点改为大写,输出。
枚举状态的时候,需要判断是否两个辅音字母挨着,如果挨着的话就跳出去,因为这可能是题目说的,一开始读错题意,后来改了改,并没有改这一步,就ok了。也有可能是到现在题意也没读懂。
代码实现:
方案一:
#include<bits/stdc++.h>
using namespace std;
#define rep(i,s,t) for(int i=s;i<=t;i++)
typedef long long ll;
const int N=1e6+5,mod=1e9+7,INF=0x3f3f3f3f;
int vis_1[300],vis_2[300],a[300][300],vis[1000];
char s[N];
int main()
{
ll i,j,k;
scanf("%s",s+1);
vis_1['a']=vis_1['e']=vis_1['i']=vis_1['o']=vis_1['u']=vis_1['w']=vis_1['y']=1;
ll t=0; //num
for(i='a';i<='z';i++)
if(!vis_1[i])
vis_2[i]=t++;
for(i=1;s[i+1];i++)
{
a[s[i]][s[i+1]]++;
}
ll maxx=0,flag=0; //flag--->zhuang tai
for(t=0;t<(1<<19);t++)
{
ll sum=0;
for(i='a';i<='z';i++)
{
if(vis_1[i])
continue;
int x=vis_2[i];
for(j='a';j<='z';j++)
{
if(vis_1[j])
continue;
int y=vis_2[j];
if(((t>>x)&1)!=((t>>y)&1))
sum+=a[i][j];
}
}
if(sum>maxx)
{
maxx=sum;
flag=t;
}
}
// cout<<flag<<"***"<<endl;
for(i='a';i<='z';i++)
{
if(flag&(1<<vis_2[i]))
vis[i]=1;
}
for(i=1;s[i];i++)
{
if(vis[s[i]]&&(!vis_1[s[i]]))
printf("%c",(char)s[i]-32);
else
printf("%c",s[i]);
}
puts("");
}
方案二:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=1e6+5,mod=1e9+7,INF=0x3f3f3f3f;
char f[20]={'b', 'c', 'd', 'f', 'g', 'h', 'j', 'k', 'l', 'm', 'n', 'p', 'q', 'r', 's', 't', 'v', 'x', 'z'};
int a[30][30],v[30][30],vis[300];
char s[N];
int main()
{
int i,j,k;
scanf("%s",s);
for(i=0;s[i+1];i++)
{
a[s[i]-'a'][s[i+1]-'a']++;
}
for(i=0;i<19;i++)
{
for(j=0;j<19;j++)
{
v[i][j]=a[f[i]-'a'][f[j]-'a'];
}
}
int maxx=0,flag=0;
for(int t=0;t<(1<<19);t++)
{
int sum=0,ss=0;
for(i=0;i<19;i++)
{
for(j=0;j<19;j++)
{
if(((t>>i)^(t>>j))&1)
{
sum+=v[i][j];
}
}
}
if(sum>maxx)
{
maxx=sum;
flag=t;
}
}
for(i=0;i<19;i++)
{
if(flag&(1<<i))
{
vis[f[i]]=1;
}
}
for(i=0;s[i];i++)
{
if(vis[s[i]])
printf("%c",s[i]-32);
else
printf("%c",s[i]);
}
puts("");
}