Codeforces Round #730 (Div. 2) A,B,C,D1题解

A

题意

给出a,b两个数,我们可以进行两个操作:要么给a,b都加上1,要么都减1( min(a,b)>0 ),求gcd(a,b) 的最大值

思路

咋们老祖宗的定理,更相减损法,gcd(a,b)=gcd(a-b,b) (a>b), 因为b可以无限增大,但是a-b不变,所以说max(gcd(a,b)) = abs(a-b), 注意如果a==b,输出0 0

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;

int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		ll  a,b;
		scanf("%lld %lld",&a,&b);
		if(a==b) printf("0 0\n");
		else if(abs(a-b)==1) printf("1 0\n");
		else
		{
			ll  g=abs(a-b);
			ll r=a%g;
			//要对比是减更快,还是加更快
			printf("%lld %lld\n",g,min(r,g-r));
		}
	}

	return 0;
} 

B

题意

给定一组数,a1,a2…an, 每次操作你可以对ai-1并且对aj+1,操作次数为任意次,最后使得这组数两两相减的绝对值之和最小。

思路

显然要使得两两相减的绝对值最小,那么直接平摊总和就是了,多余的放在最后几位,具体见代码

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int  N = 2e5+9;
ll a[N]; 
int main()
{
	int t;
	cin>>t;
	while(t--)
	{
		int n;
		ll sum=0;
		scanf("%d",&n);
		for(int i=1; i<=n; i++)
		{
			scanf("%lld",a+i);
			sum+=a[i];
		}
		ll x=sum/n;
		ll y=sum%n;
		if(y==0) printf("0\n");
		else
		{
			printf("%lld\n",(n-y)*y);
		}
	}

	return 0;
} 

C

题意

给定3张卡,他们被抽到的概率分别是c,m,p,给出一个系数v。如果抽到c, 那么c-min(c,v), m和p加上min(c,v)/2, 如果m已经为0了,则全部分给p,p+min(c,v)。 同理抽到m也是如此,直到抽到p结束,求抽取次数的期望值。

思路

这道题数据范围很小,直接爆搜就行了,要么抽c,要么抽m, 要么抽p,抽到p结束递归。注意:抽到c(m)时候,要看m©是否为0了

代码

#include<bits/stdc++.h>


using namespace std;
double ans;
const double eps=1e-6;
double v;
void dfs(double t,double c,double m,double p,double tmp)
{
	if(p<eps)
	{
		ans+=(t*tmp);
		return ;
	}
	if(c>eps)//选C 
	{
		//看m是否为0,为0就不能再分配给它了
		if(m>eps) dfs(t+1,c-min(c,v),m+min(c,v)/2,p+min(c,v)/2,tmp*c);
		else dfs(t+1,c-min(c,v),m,p+min(c,v),tmp*c); 
	} 
	if(m>eps)
	{
		if(c>eps) dfs(t+1,c+min(m,v)/2,m-min(m,v),p+min(m,v)/2,tmp*m);
		else dfs(t+1,c,m-min(m,v), p+min(m,v),tmp*m);
	}
	if(p>eps) dfs(t+1,c,v,0,tmp*p);
}

int main()
{
	
	int t;
	cin>>t;
	while(t--)
	{
		double c,m,p;
		ans=0;
		scanf("%lf %lf %lf %lf",&c,&m,&p,&v);
		dfs(0,c,m,p,1);
		printf("%f\n",ans);
	}
	
	
	return 0;
}

D1

题意

这是一道交互题,系统存在一个密码x(0~n-1), 我们每次询问x的值是多少 y,如果猜对了,则系统返回1结束,否则x=x^y,系统返回0, 继续询问,要求最多询问n次猜对密码。

思路

我们每次猜错后密码都会变化,还可能>=n, 假设初始密码为x,现在的密码为y, 那么y=x^c的形式,c代表我前面猜测的一系列数的异或值,我们可以记录下c, 从0到n-1枚举x,一定可以在n次询问内找到答案

代码

#include<bits/stdc++.h>
#define ll long long
using namespace std;
int main()
{
	
	int t;
	cin>>t;
	while(t--)
	{
		int n,k;
		scanf("%d%d",&n,&k);
		int q;
		int t=0;
		for(int i=0; i<n; i++)
		{
			printf("%d\n",i^t);
			fflush(stdout);
			t^=(i^t);
			scanf("%d",&q);
			if(q==1) break;
			
		}
		
	}

	return 0;
} 

总结

奋斗中的蒟弱,如果你对本篇博客有好的建议或者批评,欢迎指出!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值