CodeForces - 1247C

Vasya will fancy any number as long as it is an integer power of two. Petya, on the other hand, is very conservative and only likes a single integer p (which may be positive, negative, or zero). To combine their tastes, they invented p-binary numbers of the form 2x+p, where x is a non-negative integer.

For example, some −9-binary (“minus nine” binary) numbers are: −8 (minus eight), 7 and 1015 (−8=20−9, 7=24−9, 1015=210−9).

The boys now use p-binary numbers to represent everything. They now face a problem: given a positive integer n, what’s the smallest number of p-binary numbers (not necessarily distinct) they need to represent n as their sum? It may be possible that representation is impossible altogether. Help them solve this problem.

For example, if p=0 we can represent 7 as 20+21+22.

And if p=−9 we can represent 7 as one number (24−9).

Note that negative p-binary numbers are allowed to be in the sum (see the Notes section for an example).

Input
The only line contains two integers n and p (1≤n≤109, −1000≤p≤1000).

Output
If it is impossible to represent n as the sum of any number of p-binary numbers, print a single integer −1. Otherwise, print the smallest possible number of summands.

Examples
Input
24 0
Output
2
Input
24 1
Output
3
Input
24 -1
Output
4
Input
4 -7
Output
2
Input
1 1
Output
-1

Note
0-binary numbers are just regular binary powers, thus in the first sample case we can represent 24=(24+0)+(23+0).

In the second sample case, we can represent 24=(24+1)+(22+1)+(20+1).

In the third sample case, we can represent 24=(24−1)+(22−1)+(22−1)+(22−1). Note that repeated summands are allowed.

In the fourth sample case, we can represent 4=(24−7)+(21−7). Note that the second summand is negative, which is allowed.

In the fifth sample case, no representation is possible.

题意就不说了,谨以此片记录cf被hack了三道题,这道就是其中一道,比赛当晚感觉不错,过了四个题,准备写C题的时候,学长们说有一个13 6的样例hack了一百多个人,觉得自己迎来了一次上分的机会,胡乱写完之后过了,立马锁了去hack别人,hack成功四次,失败三次(不看人家代码,疯狂hack),赛后发现自己被hack了三道题(第一题替别人交了一发,不知道只算最后一次提交,被坑了五百多分)。
再说一下思路,便利K,看当前的K是不是解,n减去K个p后,判断其能拆分成多少个数,最少为其转换成二进制后有多少个一,最多为当前的数,只要K在这个范围内即可。

#include<stdio.h>
#include<algorithm>
using namespace std;
bool solve(int sum,int x) {
	int s=x;
	int j=0; 
	while(s){
		if(s&1)j++;
		s>>=1;
	}
	int ans=0;
	int cut=0;
	while(x) {
		if(x%2==1) {
			ans+=(1<<(cut));
		}
		cut++;
		x/=2;
	}
	if(sum>=j&&sum<=ans)return true;
	return false;
}
int main() {
	int n,p;
	scanf("%d %d",&n,&p);
	for(int i=0; n>=0; ++i) {
		if(solve(i,n)) {
			printf("%d\n",i);
			return 0;
		}
		n-=p;
	}
	printf("-1");
	return 0;
}

比赛完得知被hack了三道题后超级自闭,加之学长说我菜,一度想放弃学算法,太菜了啊我,还得好好训练,明年别再被说菜了!!!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值