正整数序列 Help the needed for Dexter ,UVa 11384

题目描述 Description

给定正整数n,你的任务是用最少的操作次数把序列1, 2, …, n中的所有数都变成0。每次操作可从序列中选择一个或多个整数,同时减去一个相同的正整数。比如,1,2,3可以把2和3同时减小2,得到1,0,1。
输入包含多组数据。每组仅一行,为正整数n(n≤109)。输入结束标志为文件结束符(EOF)。
对于每组数据,输出最少操作次数。

 输入输出格式 Input/output
输入格式:
输入包含多组数据,每组仅一行,为正整数n(n≤109),输入结束标志为文件结束符EOF
输出格式:
对于每组数据,输出最少操作次数
 输入输出样例 Sample input/output
样例测试点#1
输入样例:

1

6

输出样例:
3
 
思路:书上的思路就很好,因为数据不是很大用递归就很快求解,代码简洁,这个思路挺难想的。
首先用一些比较小的数据模拟一下,当n=6时,用笔操作不难发现是3次,具体如下:
1、2、3、4、5、6
从后面三个数字,也就是4、5、6开始操作,同时减min{4,5,6},剩下:
1、2、3、0、1、2       也就是说fun(6)=fun(6/2)+1
不难发现,继续操作前三个数1、2、3也可以同时操作最后的1、2,所以把这五个数操作完,就是两次:
第一次:1、0、1、0、1、0
第二次:0、0、0、0、0、0
总的来说就是3次。
 
一般的,为了平衡,保留1~n/2,把剩下的数同时减去n/2+1,得到序列1、2、3、…、n/2、0、1、…、(n-1)/2,等价于1、2、3、…、n/2,所以fun(n)=fun(n/2)+1,初始化fun(1)=1。
 
代码1如下:
 1 #include <stdio.h>
 2 int fun(int n)
 3 {
 4     return n==1?1:fun(n/2)+1;
 5 }
 6 int main()
 7 {
 8     int n;
 9     scanf("%d",&n);
10     printf("%d\n",fun(n)); 
11     return 0;
12 }

代码2如下:

 1 #include <stdio.h>
 2 int main()
 3 {
 4     int n;
 5     while(scanf("%d",&n)!=EOF)
 6     {
 7         int ans=0;
 8         for(;n>0;n/=2)
 9             ans++;
10         printf("%d\n",ans);
11     }
12     return 0;
13 }

 

posted @ 2019-10-16 09:10  Memoryヾノ战心  阅读(187)  评论(0编辑  收藏  举报