Codeforces gym 101612 Consonant Fencity (状态压缩+二进制枚举)

http://codeforces.com/gym/101612/attachments

题意:是给定你一串字符,分为元音字母和辅音字母,将辅音字母变成大写,要构成尽量多的大写字母和小写字母的组合,最后输出改变后的字符串。

思路:

由于辅音字母的数量才19个,少到可以状态压缩,将相邻点建边,边权为1,这样可以将字符串转化为1个图,相邻字符的出现次数可以表现为图的权值,然后用二进制去枚举每一种状态,然后内层去找每一步状态得到的权值,当权值最大时,保留状态,最后将所有状态为1的点改为大写,输出。
 

#include <bits/stdc++.h>
#define ll long long
using namespace std;
int main() {
	freopen("consonant.in","r",stdin);
	freopen("consonant.out","w",stdout);
	string s;
	cin>>s;
	char vowel[]= {'a','e','i','o','u','w','y'};
	int vis1[500];
	int vis2[500];
	int vis[500];
	int a[500][500];
	memset(a,0,sizeof(a));
	for(int i=0; i<7; i++) {
		vis1[vowel[i]]=1;
	}
	int z=0;
	for(int i='a'; i<='z'; i++) {
		if(!vis1[i]) {
			vis2[i]=z++;
		}
	}
	for(int i=0; s[i+1]; i++) {
		a[s[i]][s[i+1]]++;
	}
	ll maxx=0,flag=0;
	for(ll t=0; t<(1<<19); t++) {
		ll sum=0;
		for(ll i='a'; i<='z'; i++) {
			if(vis1[i])
				continue;
			ll x=vis2[i];
			for(ll j='a'; j<='z'; j++) {
				if(vis1[j])
					continue;
				ll y=vis2[j];
				// if(((t>>x)&1)!=((t>>y)&1)) // 1
				// ((1<<x)&t)!=((1<<y)&t) 2
				// 这两个等式不是等价的 因为 1式 只会返回1或者0  2式可能返回大于1的数
				if((t&(1<<(x))&&!(t&(1<<(y)))) || ((!(t&(1<<(x))))&&(t&(1<<(y)))))
					sum+=a[i][j];
			}
		}
		if(sum>maxx) {
			maxx=sum;
			flag=t;
		}
	}
	for(int i='a'; i<='z'; i++) {

		if(flag&(1<<vis2[i])) { // 如果这个字母选了 标记一下
			vis[i]=1;
		}
	}
	for(int i=0; i<s.size(); i++) {
		if(vis[s[i]]&&(!vis1[s[i]])) { // 标记过了且是辅音字母
			cout<<char(s[i]-32);
		} else
			cout<<s[i];
	}
	return 0;
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值