Codeforces Round #643 (Div. 2) 参与排名人数11475
[codeforces 1355D] Game With Array 极端的构造
总目录详见https://blog.csdn.net/mrcrack/article/details/103564004
在线测评地址https://codeforces.com/contest/1355/problem/D
Problem | Lang | Verdict | Time | Memory |
---|---|---|---|---|
D - Game With Array | GNU C++17 | Accepted | 78 ms | 7800 KB |
题目大意:构造n个元素的数组,数组中所有元素之和是s,Petya想要赢,可以设置一个k值,要求对手在原数组中选择一些元素构成新的数组,新的数组元素之和要么是k,要么是s-k.若对手无法构成这样一个新数组,Petya赢,否则,Petya输。同时还需输出原数组元素,以及k值。
赛中,看到D题AC人数是C题的2倍,果断先做D题。
题意很快弄懂,是一个,一次定胜负的游戏。
样例很快弄明白,下面这个样例,对想出该题的算法有极大的启发
Input:
3 4
Output:
NO
只能进行如下构造
1 1 2
k=0,可取出1 1 2,求和1+1+2=4,4==4-0,此时Petya can't win
k=1,可取出1,求和1,1==1,此时Petya can't win
k=2,可取出1 1,求和1+1=2,2==2,此时Petya can't win
k=3,可取出1 2,求和1+2=3,3==3,此时Petya can't win
k=4,可取出1 1 2,求和1+1+2=4,4==4,此时Petya can't win
最终结果输出NO
对下面样例,进行了重新构造
3 8
1 1 6
发现选出的数,可涉及的数据如下
1 1+1=2
1+6=7 1+1+6=8
即1 2 7 8,该数组有一个空档区间[3,6],
如何选k?只要k与s-k落在[3,6]区间内即可。
k=3,s-k=8-3=5落在[3,6]区间内
输出
YES
1 1 6
3
1≤N≤S≤10^6,数据范围,进一步验证了极端构造的正确,
极端构造如下:
前n-1个数,值全设置为1,最后的数,值设置为S-(n-1)*1,
只要能找到k与S-k落在区间[(n-1)*1+1,S-(n-1)*1-1]内,即表明找寻成功
AC代码如下
#include <stdio.h>
#define maxn 1000010
int a[maxn];
int main(){
int n,s,k,i,flag=0,l,r;
scanf("%d%d",&n,&s);
for(i=1;i<n;i++)a[i]=1;//前n-1个数,值全设置为1
a[n]=s-1*(n-1);//最后的数,值设置为S-(n-1)*1
l=1*(n-1),r=a[n];
for(i=l+1;i<r;i++)
if(l<s-i&&s-i<r){flag=1;k=i;break;}//只要能找到k与S-k落在区间[(n-1)*1+1,S-(n-1)*1-1]内,即表明找寻成功
if(!flag)printf("NO\n");
else{
printf("YES\n");
for(i=1;i<n;i++)printf("%d ",a[i]);
printf("%d\n",a[n]);
printf("%d\n",k);
}
return 0;
}