[codeforces 1355D] Game With Array 极端的构造

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

ProblemLangVerdictTimeMemory
D - Game With Array GNU C++17Accepted78 ms7800 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;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值