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的数组,数组内的元素代表山的高度。
——接下来你可以任意排序,使得最终的数组满足一下要求:
- 第一座山和第n座山相差最小。
- 在满足1的基础上,使得难度最大。若相邻两个元素是非递减的,难度+1。
题解:
——水题,比赛时看错题意了,以为只有相邻元素递增才会难度+1。
- 先排序,可以找到相差最小的两个山的下标(pos-1),pos。
- 接着输出[pos,n],[1,pos-1]就是答案。
- 注意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的幂
- 如果n是奇数,唯一的办法就是减去一个奇数因子(因为所有的因子都是奇数)。这样我们将得到一个不是2的幂的偶数(情况2)。因为D是n的因子,那么n-D也必须能被D整除,因为D是奇数,n-D不能是2的幂。
- 如果n是偶数且不是2的幂,则表示n有一个奇数因子。通过减去这个奇数除数,我们将得到n-D是奇数(情况1)。
现在让我们证明每一步都减去一个奇数,结果就是赢。
因为每个质数都是奇数或2,所以给另一个玩家一个奇数是可行的,因为它要么是一个质数(另一个玩家就输了),要么他们会移动给你另一个不是2的幂的偶数。你可以继续这个过程,因为你永远不会落在一个失败的数字上,因为游戏必须在有限的步数之后结束,你的对手必须总是失败。
所以我们证明了n是奇数是输的,n是偶数不是2的幂是赢的。
- 如果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;
}