正整数序列 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
输出格式:
对于每组数据,输出最少操作次数
输入包含多组数据,每组仅一行,为正整数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 }
我不怕千万人阻挡,只怕自己投降…