Codeforces Round #734 (Div. 3)题解(A、B1、B2、C)


A. Polycarp and Coins

题目大意:
有两种硬币,一种1块的,一种两块的,让你使用两种硬币表示一个数n,且两种硬币数量尽可能小

思路:

先算出用1块的和两块的和一起(即3块)需要用多少个,n/3

再看余数,如果n%3 == 0,则刚好表示完
n%3 == 1,则再需要一个1块的
n%3 == 2 ,则再需要一个两块的

AC代码:

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		ll n;
		scanf("%lld",&n);
		ll q1=n/3;
		ll q2=n/3;
		if(n%3==2)q2++;
		if(n%3==1)q1++;
		printf("%lld %lld\n",q1,q2); 
	}
	return 0;
} 

B1. Wonderful Coloring - 1

题目大意:
给你一个字符串,要求用2种颜色去填涂字符,可以选择不填
满足要求:
1.涂两种颜色的字符个数相等
2.每种颜色不能有相等的数
问每种颜色最多能涂多少个字符

思路:
如果一个字符出现次数大于等于2次,则可以直接对答案加1
如果一个字符出现次数小于2次的,我们将其累加起来,然后分摊到2种颜色上
多余的不涂

AC代码:

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
map<int ,int >map1;
int f[27];
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		string x;
		cin>>x;
		int len=x.length();
		int ans=0;
		memset(f,0,sizeof(f));
		for(int i=0;i<len;++i){
			int p=x[i]-'a'+1;
			f[p]++;
		}
		int sum=0;
		for(int i=1;i<=27;++i){
			if(f[i]==1)sum++;
			if(f[i]>=2)ans++;
		}
		printf("%d\n",ans+sum/2);
	}
	return 0;
} 

B2. Wonderful Coloring - 2

题目大意:
相对B1来说变成了用k种颜色涂,然后由字符变成了数字,输出涂色情况(不涂用0,有颜色用1-k)

思路:
先用B1的思路计算出每种颜色最多涂多少次sum

然后将序列按照数的大小排序,并且记录编号,依次填即可,如果颜色出现次数超过sum则不涂

AC代码:

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int maxn=2e5+3;
map<int ,int >map1;
map<int ,int >map2;
struct a_node{
	int x;
	int id;
}a[maxn];
int ans[maxn];
bool cmp(a_node a,a_node b){
	return a.x<b.x;
}
int main(){
	int T;
	scanf("%d", &T);
	while(T--){
		int n,k;
		scanf("%d %d",&n,&k);
		map1.clear();
		map2.clear();
		int sum=0;
		int psum=0;
		for(int i=1;i<=n;++i){
			scanf("%d",&a[i].x);
			map1[a[i].x]++;
			a[i].id=i;
			if(map1[a[i].x]==k)sum++;
			if(map1[a[i].x]>k)psum++;
			ans[i]=0;
		}
		int q=sum;
		sum+=(n-sum*k-psum)/k;
		for(int i=1;i<=n;++i){//先处理出现次数大于等于k的 
			if(map1[a[i].x]>=k){
				ans[i]=++map2[a[i].x];
				if(map2[a[i].x]>k)ans[i]=-1;
			}
		}
		sort(a+1,a+n+1,cmp);
		int t=1;
		int p=0;
		for(int i=1;i<=n;++i){//再处理小于等于k的 
			if(ans[a[i].id]!=0)continue;
			if(q+p==sum)continue;//如果该颜色数量已经达到最大则不涂 
			ans[a[i].id]=t;
			t++;
			if(t>k)t=1,p++;
		}
		for(int i=1;i<=n;++i){
			if(ans[i]==-1)ans[i]=0;
			printf("%d ",ans[i]);
		}
		printf("\n");
	}
	return 0;
} 

C. Interesting Story

题目大意:
定义一个有趣的故事由一个或多个字符串组成,且‘a’、‘b’、‘c’、‘d’、‘e’其中某个字母出现的次数大于其他字母出现的次数总和,则为有趣的故事。

现在给你n个字符串,问最多可以组成多少个有趣的故事

思路:
暴力算出每一个字符串的sum值,表示对于字母k(‘a’、‘b’、‘c’、‘d’、‘e’其中一个),出现次数与其他字母出现次数的差值

然后从大到小排序
挨个加入组成一个故事,取最大值

至于n^2怎么过2e5的我也不知道QWQ
AC代码:

#include<bits/stdc++.h>
#define ll long long 
using namespace std;
const int maxn=2e5+3;
string a[maxn];
int b[maxn];
bool cmp(int x,int y){
	return x>y;
}
int main(){
	int T;
	scanf("%d",&T);
	while(T--){
		int ans=0;
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;++i)
			cin>>a[i];
		for(int k=0;k<=4;++k){
			int tot=0;
			for(int i=1;i<=n;++i){
				int len=a[i].length();
				int sum=0;
				for(int j=0;j<len;++j){
					if(a[i][j]=='a'+k)sum++;
					else sum--;
				}
				b[++tot]=sum;
			}
			sort(b+1,b+n+1,cmp);
			int p=0;
			for(int j=1;j<=n;++j){
				p+=b[j];
				if(p<=0)break;
				ans=max(j,ans);
			}
			
		}
		printf("%d\n",ans);
	}
} 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值