【Jason's_ACM_解题报告】Help is needed for Dexter

Help is needed for Dexter

Dexter is tired of Dee Dee. So he decided to keep Dee Dee busy in a game. The game he planned for her is quite easy to play but not easy to win at least not for Dee Dee. But Dexter does not have time to spend on this silly task, so he wants your help.

 

There will be a button, when it will be pushed a random number N will be chosen by computer. Then on screen there will be numbers from 1 to N. Dee Dee can choose any number of numbers from the numbers on the screen, and then she will command computer to subtract a positive number chosen by her (not necessarily on screen) from the selected numbers. Her objective will be to make all the numbers 0.

 

For example if N = 3, then on screen there will be 3 numbers on screen: 1, 2, 3. Say she now selects 1 and 2. Commands to subtract 1, then the numbers on the screen will be: 0, 1, 3. Then she selects 1 and 3 and commands to subtract 1. Now the numbers are 0, 0, 2. Now she subtracts 2 from 2 and all the numbers become 0.

 

Dexter is not so dumb to understand that this can be done very easily, so to make a twist he will give a limit L for each N and surely L will be as minimum as possible so that it is still possible to win within L moves. But Dexter does not have time to think how to determine L for each N, so he asks you to write a code which will take N as input and give L as output.

 

Input and Output:

Input consists of several lines each with N such that 1 ≤ N ≤ 1,000,000,000. Input will be terminated by end of file. For each N output L in separate lines.

 

SAMPLE INPUT 

 SAMPLE OUTPUT

1

2

3

1

2

2



此题自行解出,看来是Liu觉得前面难题太多,是时候刷个水题放松一下了。

开玩笑,其实Liu选此题的目的很明确,旨在提示我们遇到此类问题,要善于总结,如果发现了其局部同居部的相似性,甚至发现了其分治的特性,那么我们可以采用递归的手法解决此题。

我是这样做出此题的:

开始,我选N=6,然后将对于第一次subtract,枚举1~N所有可能,发现每次减“中位数”最优。

然后,由于发现第一次减去中位数后,可以分成两个已知的情况(N为奇数时,左边是1~N/2,右边是1~N/2;N为偶数时,左边是1~N/2,右边是1~N/2-1,很显然左右顺序无所谓),这样对N求解就变成了对N/2求解再加1了。

至此,我发现了一个令人满意的递归性质。

接下来Liu直接采用此方法解决了。

但是我并不满足,2是一个很美妙的数字,在分析中我们恰恰是不断的碰到2这个数字,于是,稍作思考,求解方法就变成了求解满足等式 2^p<=N<=2^p-1 的p值了。

很显然其实两种算法是完全相似的,前者是Liu为了锻炼读者使用递归手法的能力,后者无非是一种取巧的运算,朋友们可以自行思考。


附代码如下:

我的方法:

#include<cstdio> 
#include<cmath>

using namespace std;

int main(){
	int n,ans;
	while(scanf("%d",&n)!=EOF){
		ans=log10(n)/log10(2)+1;
		printf("%d\n",ans);
	}
	return 0;
}

Liu的方法:

#include<cstdio> 
#include<cmath>

using namespace std;

int f(int x){
	if(x==1)
		return 1;
	else 
		return f(x/2)+1;
}

int main(){
	int n,ans;
	while(scanf("%d",&n)!=EOF){
		printf("%d\n",f(n));
	}
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值