Codeforces Round #764(div3)A~D

这次的A~D都是思维题,都比较简单。
A.Plus One on the Subset
在这里插入图片描述
题意:给定n个数,每次可以选择任意数量的数+1,求最短的+1次数使得全部的数字相等
题解:排序,因为最短次数就是让最小的跟最大的相等,所以输出最大的减去最小的即可。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int N=1e2;
int a[N];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		cin>>n;
		for (int i=0;i<n;i++) cin>>a[i];
		sort (a,a+n);
		cout<<a[n-1]-a[0]<<endl;
	}
	return 0;
}

B.Make AP
在这里插入图片描述
题意:给定3个数,不能改变顺序,可以选择任意一个数乘以一个正整数,问这三个数变化后(可以不变)能否成等差数列
题解:a,b,c三个数,求出b-a,c-b,如果这两个相等说明能变成等差数列。如果不相等,则先考虑变a,b-(c-b)就是a变化后的数,如果能整除a且是除以a后是正整数,则能变成等差数列。然后用相同的方式变b跟c

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		long long a,b,c;
		cin>>a>>b>>c;
		long long t1=c-b,t2=b-a,t3=(c-a)/2;
		if (t1==t2)
		{
			cout<<"YES"<<endl;
			continue;
		}
		bool flag=false;
		if ((b-t1)%a==0 && b!=t1 && (b-t1)/a>0)
		{
			cout<<"YES"<<endl;
			continue;
		}
		if ((b+t2)%c==0 && b-t2!=0 && (b+t2)/c>0)
		{
			cout<<"YES"<<endl;
			continue;
		}
		if (t3*2==c-a && (c-t3)%b==0 && c!=t3 && (c-t3)/b>0)
		{
			cout<<"YES"<<endl;
			continue;
		}
		cout<<"NO"<<endl;
	}
	return 0;
}

C.Division by Two and Permutation
在这里插入图片描述
题意:给定n个数,可以用ai/2向下取整来替代ai(不限次数),问能否让数组变成1n的数且1n每个数都要出现且仅出现一次
题解:先将小于n的数取出,然后再遍历,将ai变成小于n的数然后看看/2后是否出现过,如果没出现过则取出,出现过则继续往下/2知道变成0为止,如果变成0则说明不能满足题目要求,输出NO

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
const int N=55;
int a[N];
bool f[N];
bool p[N];
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n;
		cin>>n;
		for (int i=0;i<n;i++) 
		{
			cin>>a[i];
			f[i+1]=true;
			p[i]=true;
		}
		sort (a,a+n);
		bool flag=true;
		for (int i=0;i<n;i++)
			if (a[i]<=n && f[a[i]])
			{
				p[i]=false;
				f[a[i]]=false;
			}else if (a[i]>n) break;
		for (int i=0;i<n;i++)
		{
			if (p[i])
			{
				int t=a[i];
				while(t>n) t=floor(1.0*t/2);
				while(!f[t] && t>0)
				{
					t=floor(1.0*t/2);
				}
				if (t<=n && t>0 && f[t])
				{
					f[t]=false;
				}else
				{
					flag=false;
					break;
				}
			}
		}
		if (flag) cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
	}
	return 0;
}

D.Palindromes Coloring
在这里插入图片描述
在这里插入图片描述
题意:给定一个长度为n的字符串,从里面选出字母(不一定全选完),组成k个回文字符串后问最短的回文字符串的最大长度是多少
题解:统计每个字母的数量,然后将每个字母中两两为一对统计对数,因为要求最短的最大值,将这些组成一对的字母均分为k组,这样每一组的数量就是相同的都是最短的,多出来的字母全部变成单个的,如果个数大于k说明能在k组回文字符串中间加入这些字母,所以+1。

#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <queue>
using namespace std;
int a[27];
bool cmp(int a,int b)
{
	return a>b;
}
int main()
{
	int T;
	cin>>T;
	while(T--)
	{
		int n,k;
		cin>>n>>k;
		string s;
		cin>>s;
		for (int i=0;i<27;i++) a[i]=0;
		for (int i=0;i<s.length();i++) a[s[i]-'a']++;
		int t1=0,t2=0;
		for (int i=0;i<27;i++)
		{
			t2+=a[i]%2;
			t1+=a[i]/2;
		}
		int p=t1%k,res=t1/k;
		res*=2;
		if (t2>=k) res++;
		else if (p*2+t2>=k) res++; 
		cout<<res<<endl;
	}
	return 0;
}
  • 5
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值