Codeforces Round #726 (Div. 2),A~D题

本文详细解析了Codeforces Round #726 (Div. 2)的四道题目,包括Arithmetic Array(求最少添加非负数使数组平均值为1)、Bad Boy(求使Anton走步数最多的溜溜球放置位置)、Challenging Cliffs(求排序后相邻山峰差距最小且难度最大的排列)和Deleting Divisors(分析Alice和Bob游戏的获胜策略)。
摘要由CSDN通过智能技术生成

题目提交链接

A题:Arithmetic Array

题意:
——给出长度为n的数组。你可以在该数组的后面添加任意的非负数,使得最后的该数组的平均值为1,问最少添加几个非负数可以达到要求。

题解:
——水题,略。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,x,sum=0;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
		{
			scanf("%d",&x);
			sum+=x;
		}
		if(sum<n)
			printf("1\n");
		else
			printf("%d\n",sum-n);
	}
	return 0;
}

B题:Bad Boy

题意:
——Riley是一个坏男孩,这天他打算戏弄它的朋友Anton。
——已知Anton身处 n*m的网格中,位置为(x,y)。
——Riley有两个溜溜球,他可以把溜溜球放到任意位置,而Anton必须把溜溜球捡回来并返回到原本的位置。
——问溜溜球放置在哪个位置,Anton走的步数更多。

注意:溜溜球可放置在同一位置,答案有多组时输出任意一组即可。

题解:
——步数最大:2*(n+m),放置在左下角和右上角。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m,x,y;
		scanf("%d %d %d %d",&n,&m,&x,&y);
		int x1=n;
		int y1=1;
		int x2=1;
		int y2=m;
		printf("%d %d %d %d\n",x1,y1,x2,y2);
	}
	return 0;
}

C题:Challenging Cliffs

题意:
——给出长度为n的数组,数组内的元素代表山的高度。
——接下来你可以任意排序,使得最终的数组满足一下要求:

  1. 第一座山和第n座山相差最小。
  2. 在满足1的基础上,使得难度最大。若相邻两个元素是非递减的,难度+1。

题解:
——水题,比赛时看错题意了,以为只有相邻元素递增才会难度+1。

  1. 先排序,可以找到相差最小的两个山的下标(pos-1),pos。
  2. 接着输出[pos,n],[1,pos-1]就是答案。
  3. 注意n=1和n=2时需单独输出。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=2e5+1100;
const int INF=0x3f3f3f3f;
int a[N];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		for(int i=1;i<=n;i++)
			scanf("%d",&a[i]);
		sort(a+1,a+1+n);
		if(n==1)
		{
			printf("%d\n",a[1]);
			continue;
		}
		if(n==2)
		{
			printf("%d %d\n",a[1],a[2]);
			continue;
		}
		int pos=1,mind=INF;
		for(int i=2;i<=n;i++)
		{
			if(mind>a[i]-a[i-1])
			{
				mind=a[i]-a[i-1];
				pos=i;
			}
		}
		printf("%d",a[pos]);
		for(int i=pos+1;i<=n;i++)
			printf(" %d",a[i]);
		for(int i=1;i<=pos-1;i++)
			printf(" %d",a[i]);
		printf("\n");
	}
	return 0;
}

D题:Deleting Divisors

题意:
——Alice和Bob玩游戏。
游戏规则:给定一个正整数n,他们俩开始轮流对n进行运算。每个回合,玩家可以从n中减去一个非(1或n)的因数。在他/她的回合中不能移动的玩家输。Alice总是先手。

官方题解:
——不容易实现必败态:谁面对素数谁必败。但因为是减因子,使n变为素数不易得。

——始终让自身处于不败态:丢给对手一个奇数,若该奇数为素数,你就赢了,若不是,也没关系,对手肯定会还你一个不是2的幂的偶数,你就可以继续丢给对手一个奇数,你始终可以处于不败之地。

分三种情况:
1). n是奇数
2). n是偶数,n不是2的幂
3). n是2的幂

  1. 如果n是奇数,唯一的办法就是减去一个奇数因子(因为所有的因子都是奇数)。这样我们将得到一个不是2的幂的偶数(情况2)。因为D是n的因子,那么n-D也必须能被D整除,因为D是奇数,n-D不能是2的幂。
  2. 如果n是偶数且不是2的幂,则表示n有一个奇数因子。通过减去这个奇数除数,我们将得到n-D是奇数(情况1)。

现在让我们证明每一步都减去一个奇数,结果就是赢。
因为每个质数都是奇数或2,所以给另一个玩家一个奇数是可行的,因为它要么是一个质数(另一个玩家就输了),要么他们会移动给你另一个不是2的幂的偶数。你可以继续这个过程,因为你永远不会落在一个失败的数字上,因为游戏必须在有限的步数之后结束,你的对手必须总是失败。

所以我们证明了n是奇数是输的,n是偶数不是2的幂是赢的。

  1. 如果n是2的幂呢,则因子全是偶数。你可以在一次移动中做两件事,将n减半或使n成为一个不是2的幂的偶数(我们上面已经证明了这是另一个玩家的获胜的状态)。唯一的最佳方法是将n减半,使它变成2的另一个幂。玩家继续这样,谁最终面对的是2,谁就输了。即如果log2(n)是偶数,则Alice赢,否则Bob赢。

代码:

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int N=2e5+1100;
const int INF=0x3f3f3f3f;
int a[N];
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n;
		scanf("%d",&n);
		if(n%2==1)
		{
			printf("Bob\n");
			continue;
		}
		int cnt=0;
		while(n%2==0)
		{
			cnt++;
			n/=2;
		}
		if(n>1)
			printf("Alice\n");
		else if(cnt%2==0)
			printf("Alice\n");
		else
			printf("Bob\n");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值