Codeforces Round #834 (Div. 3) A~E题解

原题地址:Codeforces Round #834 (Div. 3)

题目:A. Yes-Yes?

题意:

        给定一个字符串s,看这个字符串s是不是多个Yes组成的字符串ans = “YesYesYesYesYes...”的子串,因为题目所给定的s的长度为50,那么我们定义一个长度为100的“YesYes...”串ans,然后看s是否是ans的子串即可

代码

        

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 1e5+10;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
	int t;
	cin >> t;
	while(t--)
	{
		string s = "YesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYesYes";
		string s1;
		cin >> s1;
		if(s.find(s1)!=-1)
			cout << "YES" << endl;
		else	
			cout << "NO" << endl;
	} 
	return 0;
 } 

题目:B. Lost Permutation

题意:

        给定一个长度为m的数组a,和一个s,问是否可以向a添加几个元素让数组a满足permutation,并保证添加的元素的和等于s,做法:直接暴力即可,把未出现的数字从小到大枚举,如果和等于s即输出yes,要是和不等于s就输出no即可

代码:

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 110;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
	int t;
	cin >> t;
	while(t--)
	{
		memset(b,0,sizeof b);
		ll m,s;
		cin >> m >> s;
		for(int i=1;i<=m;i++)
		{
			int num;
			cin >> num;
			b[num] = 1;
		} 
		ll sum=0;
		int flag=0;
		int res=0;
		for(int i=1;i<=N;i++)
		{
			if(!b[i])
			{
				sum+=i;
				res++;
				b[i] = 1;
			}
			if(sum==s)
			{
				break;
			}
			else if(sum>s)
			{
				flag=1;
				break;
			}
		}
		for(int i=1;i<=m+res;i++)
		{
			if(!b[i])
			{
				flag=1;
				break;
			}
		}
		if(!flag)
			cout << "YES" << endl;
		else
			cout << "NO" <<endl;
	} 
	return 0;
 } 

题目:C. Thermostat

题意:

        实打实要将a变成l,r之间的任意一个数,但是要满足变了之后的a与原来的a比较要大于x,比如

0 10 5

3 7

这个案例,3直接变到7是不可以的,我们可以将3变到10,10变到7不可以,那么10变成0,最后0变到7,一共三次,所以此题的算法就是,a不断地变为左右边界,直到满足a-b >= x,由此可见,最多的次数一定是三次,因为左右边界最多各去一次。模拟即可

代码:

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 110;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
	int t;
	cin >> t;
	while(t--)
	{
		ll l,r,d,x,y;
		cin >> l >> r >> d;
		cin >> x >> y;
		if(x==y)
		{
			cout << 0 << endl;
			continue;		
		}
		int ans=1;
		int flag=0;
		//ll ma=max(y-x,x-y);
		ll ma = abs(y-x);
		while(ma<d)
		{
			ans++;
			int aa = max(x-l,r-x);
			if(ans>4||aa<d)
			{
				flag=1;
				break;
			}
			ma = 0;
			int xx = x;
			if(x-l>=d)
			{
				x = l;
				ma = abs(y-x);
			}
			if(r-xx>=d&&r-y>ma)
			{
				x = r;
				ma = abs(y-x);
			}
		}
		if(flag)
			cout << -1 << endl;
		else
			cout << ans << endl;
	} 
	return 0;
 } 

题目:D. Make It Round

题意:

        给定一个n和m,k的取值范围在1~m,求出最大的n*k并满足有最多的末尾0。首先10 = 2*5,所以要有末尾0,首先必须出现2和5,所以我们先分解n,看一下n有多少个5,多少个2,假设n分解之后有4个2,1个5,它本身1个2和1个5相乘等于10,所以剩下3个2,那么此时,k就先补3个5,既5*5*5 = 125,如果此时k还没有超出范围的话,就继续乘10,如果乘10后超出范围了,就在1~9之间相乘,找到最大的那个k。如果k在补5的时候超出范围了,比如m = 26,我们就不能5*5*5了,只需要k = 5*5 = 25即可

最后输出n*k即可

代码:

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 2e5+10;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
	int t;
	cin >> t;
	while(t--)
	{
		ll n,m;
		cin >> n >> m;
		ll k=1;
		int c2=0,c5=0;
		int nn = n;
		while(nn%2==0)
		{
			c2++;
			nn/=2;
		}
		nn=n;
		while(nn%5==0)
		{
			c5++;
			nn/=5;
		}
		int d = abs(c2-c5);
		if(c2>c5)
		{
			while(d--&&k*5<=m)
			{
				k*=5;
			}
		}
		else
		{
			while(d--&&k*2<=m)
			{
				k*=2;
			}
		}
		//cout << k << endl;
		while(k*10<=m)
		{
			k*=10;
		}
		for(int i=1;i<=10;i++)
		{
			if(k*i>m)
			{
				k*=(i-1);
				break;
			}
		}
		cout << n*k << endl;
	} 
	return 0;
 } 

题目:E. The Humanoid

题意:

        给定一个n和h,h为当前的能量,有n个能量,类似大鱼吃小鱼的游戏,你只能吃小于h的能量并且吃完后h可以增加a[i]/2,且有俩瓶绿的一个蓝的,绿的可以将h提高俩倍,蓝的可以将h提高三倍,求怎么分配药瓶能够使得吃到最多的能量个数。

做法就是:药瓶的使用的顺序一共有3种可能,2 2 3 ,2 3 2 , 3 2 2,这三种吃药顺序,我们只需要每次吃药顺序都模拟一边,找出最多的个数即可

代码:

#include<bits/stdc++.h> 
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
#include<map>
#include<string.h> 
typedef long long ll;
using namespace std;
const int N = 2e5+10;
const int mod = 1e9+7;
ll a[N],b[N],c[N];
//string s1[N],s2[N],s3[N];
int main(void)
{
	int t;
	cin >> t;
	while(t--)
	{
		int n;
		int res=0,res1=0;
		ll h;
		cin >> n >> h;
		ll hh = h;
		for(int i=1;i<=n;i++)
		{
			cin >> a[i];
		}
		sort(a+1,a+n+1);
		int cc=1;
		for(int i=1;i<=n;i++)
		{
			if(h>a[i])
			{
				res1++;
				h += a[i]/2;
			}
			else
			{
				if(cc==1)
				{
					h*=2;
					i--;
					cc++;
				}
				else if(cc==2)
				{
					h*=2;
					i--;
					cc++;
				}
				else if(cc==3)
				{
					h*=3;
					i--;
					cc++;
				}
				else
				{
					break;
				}
			}
		}
		res = max(res,res1);
		cc=1;
		h = hh;
		res1=0;
		for(int i=1;i<=n;i++)
		{
			if(h>a[i])
			{
				res1++;
				h += a[i]/2;
			}
			else
			{
				if(cc==1)
				{
					h*=2;
					i--;
					cc++;
				}
				else if(cc==2)
				{
					h*=3;
					i--;
					cc++;
				}
				else if(cc==3)
				{
					h*=2;
					i--;
					cc++;
				}
				else
				{
					break;
				}
			}
		}
		res = max(res,res1);
		cc=1;
		h = hh;
		res1=0;
		for(int i=1;i<=n;i++)
		{
			if(h>a[i])
			{
				res1++;
				h += a[i]/2;
			}
			else
			{
				if(cc==1)
				{
					h*=3;
					i--;
					cc++;
				}
				else if(cc==2)
				{
					h*=2;
					i--;
					cc++;
				}
				else if(cc==3)
				{
					h*=2;
					i--;
					cc++;
				}
				else
				{
					break;
				}
			}
		}
		res = max(res,res1);
		cout << res << endl;
	} 
	return 0;
 } 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值