boj 510

Description
Employees of Baidu like to play a game called Making Numbers. It goes like this: there are two players in the game, one is called little A, the other little B. There are some cards with a number on each one of them, little A chooses a number X from 1 to N randomly, while little B has to choose some cards, the sum of which equals X. Now there are already M cards with numbers, and K blank cards. At the beginning of the game, little B is allowed to write numbers on the blank cards. Now little B wants to know, if it is possible to write some numbers that will assure him of the victory, that is to say, if it is possible for him to make up any number from 1 to N with the cards.

Input
The input consists of several test cases. The first line is an integer T , in the second line of each case are 3 numbers, N M K, the second line shows the number that is already written on M cards. 1<=N<=99999999,0<=M<=19,1<=K<=19 The numbers in the second line are above 0, smaller than or equals N, in non-descending order. Input ends with 0 0 0, which doesn't need to be processed.

Output
If little B can make it, output "YES", else output "NO".

Sample Input

3 15 0 4
12 3 2
3 3 3
13 3 2
3 3 3


Sample Output

YES
YES
NO

思路:

对于一个数N,找出最小的m,使这m个数可以组成1~N之间的任何数,则做法就是将N写成2的幂的和,例如:

N=14,14=1+2+4+7,则m=4,即1,2,4,7四个数可以组成1~N之间的任何数,这是用到了二进制的思想。

其实如果从N=1开始来看的话,此时m=1,1可以构成1~1之间的任何数;

当N=2时,因为1已经构成了1~1之间的任何数,即构成1的所有数之和sum=1,此时只需添加sum+1进入,则对于N∈[sum+1,sum+sum+1]之间都可以构成,其实这也是与二进制的思想相符合的,如下

N=1:(1)

N=2,3(1,,2)

N=4,5,6,7(1,2,4)

N=8,9,10,11,12,13,14,15(1,2,4,8)

...

N=...(1,2,34,8...2^n)

可以看到括号里即为2的幂。

所以对于本题,初始化sum=0,如果当前的数大于sum+1,则sum+=sum+1,直到小于等于sum+1,然后再加上当前的数。同时注意k是否大于0还有剩余,一直sum+=sum+1,最后判断sum和n的大小对应输出即可

代码:

#include<iostream>
using namespace std;
int main()
{
	int t;
	scanf("%d",&t);
	while(t--)
	{
		int n,m,k,sum = 0;
		scanf("%d %d %d",&n,&m,&k);
		for(int i=0;i<m;i++)
		{
			int tmp;
			scanf("%d",&tmp);
			while(tmp>sum+1&&k>0)
			{
				sum +=sum+1;
				k--;
			}
			if(tmp<=sum+1)
				sum+=tmp;
		}
		while(k--) sum+=sum+1;
		if(sum<n) printf("NO\n");
		else printf("YES\n");
	}
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值