训练赛4题解

A.Mezo playing zoma

题意

先给一个字符串的长度,然后你输入一个字符串(全部由LR组成)然后一个东西本来从坐标原点0处,收到L往左走1,收到R往右走1,但是每个指令都有坏的可能,也就是说不知道哪个指令可以接收到,问所有的可能

思路

可以这么想,所有L都失效所有R都有效那么他可以最多往右走y个(y是R指令的个数),然后一个R失效就会走y-1,y种情况,同理如果所有R都失效,就有x种情况,x是L的个数,所以就一共有X+Y+1种情况(加1是因为都失效还有在原点处的情况)其实也就是n+1

代码

#include<iostream>
#include<cstring>
#include<string> 
using namespace std;
int main()
{
	char s[100010];
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	 cin>>s[i];
	int sum1=0;
	int sum2=0;
	for(int i=1;i<=n;i++)
	{
		if(s[i]=='R') sum1++;
		if(s[i]=='L') sum2++;
	}
	cout<<sum1+sum2+1<<endl;
	return 0;
}

B.Just eat it

题意

给定一个数组长度为n 数组的每个单位有正有负,第一次是把所有的数都加起来了,第二次是选定一个区间,这个区间可以使任意的但是不能是(1,n)也就是和一次重叠,如果第一次大于第二次输出yes ,如果第二次大于等于第一次输出no

思路

这题可以利用前缀和,只要每一个位置的前缀和为负的那么不选它而是选它后面的所有区间肯定比选了他大,所以就输出no,同理还得求后缀和,只要前缀和和后缀和有一个是小于0的就是no(因为加个他肯定比不加他小因为是个辅助嘛)反之就输出yes

代码

#include<iostream>
#include<cstring>
typedef long long ll;
const int N=100010;
int a[N];
ll s1[N],s2[N]; 
using namespace std;
int main()
{
	int n,t;
	int f=0;
	cin>>t;
	while(t--)
	{
		f=0;
		memset(s1,0,sizeof s1);
		memset(s2,0,sizeof s2);
		cin>>n;
		for(int i=1;i<=n;i++)
		 cin>>a[i];
		for(int i=1;i<=n;i++)
		{
			s1[i]=s1[i-1]+a[i];
			if(s1[i]<=0)
			 f=1;
		}
		for(int i=n;i>=1;i--)
		{
			s2[i]=s2[i+1]+a[i];
			if(s2[i]<=0)
			 f=1;
		} 
		if(f)
		 cout<<"NO"<<endl;
		else
		 cout<<"YES"<<endl;
	}
	return 0;
}
 

C.fadi and lcm

题意

给你一个数x,求两个数a,b 使得a乘b等于x,且a,b的最大值最小,求a,b
例如 4 就输出1,4(ab不能相等),如果6就输出2,3不能输出1,6 要ab的最大值最小吗

思路

从a的最大值开始去试,a的最大值是sqrt(x),然后判断x是否能整除a如果能得到商b,再判断a和b的最小公倍数是否为x 如果是的话输出a,b 如果不行继续a减1继续往下找

代码

#include<iostream>
#include<cmath>
using namespace std;
typedef long long ll;
ll gcd(ll a,ll b)
{
	if(b==0)
	 return a;
	return gcd(b,a%b);
}//a>b
int main()
{
	ll x; 
	cin>>x;
	ll a=sqrt(x);
	for(ll i=a;i>=1;i--)
	{
		if(x%i==0)
		{
			ll b=x/i;
			ll g=gcd(i,b);
			if(i/g*b==x)
			{
				cout<<i<<" "<<x/i<<endl;
				break;
			}
		}
	}
	return 0;
}
 

E.Deadline

题意

给你一个n一个d,然后你需要在规定的n天里完成d天才能完成的任务,你可以花x天优化,优化完后d天的任务 将变成 d/(x+1),优化也是需要天数的,因此优化完后再完成共需要x+d/(x+1)(向上取整),给你一个n给你一个d 问是否能完成任务

思路

这题显然就是找x的合适值,找x使x+d/(x+1)最小,式子可以变成x+1+d/(x+1)-1,由基本不等式可以得到当x+1=d/(x+1)时最小即x等于sqrt(d)-1时最小,但这题 sqrt d 可能是小数,所以要从 x-2开始到x-1,求最小值再与n比较

代码

#include<cmath>
#include<cstdio>
using namespace std;
int main()
{
	int t,n,d;
	cin>>t;
	while(t--)
	{
		cin>>n>>d;
		int x=sqrt(d);
		int minn=d;
		for(int i=max(x-2,1);i<=x-1;i++)//x可能是小数,从-2一直预处理到-1求最小值 
		{
			int temp=i+d/(i+1)+(d%(i+1)!=0);
			minn=min(minn,temp);
		}
		if(minn<=n)
		 cout<<"YES"<<endl;
		else
		 cout<<"NO"<<endl;
	}
	return 0;
} 

F.yet another meme problem

题意

给一个A再给一个B然后a属于1到Ab属于1到B,问 a,b的对数满足以下要求:
a*b+a+b=conc(a,b), conc(12,23)=1223, conc(100,11)=10011

思路

其实就是满足ab+a+b=a10^n+b(n就是b的位数)所以得到 b+1=10^n
b就是 10的n次幂减一也就是 9 99 999 99999 999999 。。。,所以满足条件是由b限制的,看小于b的有多少 9 99 999 。、。。,这就是满足要求的b的个数sum,然后A就是a满足要求的个数,a对条件没有影响

代码

#include<iostream>
using namespace std;
typedef long long ll;
int main()
{
	int t;
	cin>>t;
	ll a,b;
	while(t--)
	{
		cin>>a>>b;
		ll cnt=0;
		ll sum=0;
		while(cnt<=b)
		{
			cnt=cnt*10+9;
			sum++;
		}
		sum--;
		cout<<a*sum<<endl;
	}
	return 0;
}
发布了8 篇原创文章 · 获赞 0 · 访问量 116

猜你喜欢

转载自blog.csdn.net/xgx984826498/article/details/104009139
今日推荐