3n+1_problem_Uva
2016-04-30 22:49
387 查看
这道题,其实说难也难,说简单也简单,关键在其测试数据。如果测试数据很苛刻,就很难了(参看博客UVa Problem 100 The 3n+1 problem (3n+1 问题))。
这里,我要写两点想法:第一,题目中说求数字i,j之间的最大循环节长度,但是样例输入却都是按min,max的顺序给出,这让我们产生了一种错觉:输入就是按较小数、较大数输入的,这也是我多次TL的原因。记住:当题目要求模棱两可的时候,一定要注意其真正的意思,不要带入自己的观念。第二,我列举了10以内数的循环节长度,发现相邻两个数中奇数较大时,奇数的循环节长度一般比偶数的大;但是如果偶数较大时,这个就不成立,因此,当一个范围的最大数是偶数的时候,要单独计算其循环节长度,剩下的就归结为前一类情况了,也就可以只计算奇数的循环节长度(这里是不严格的推广)。另外,一个范围(min到max)内的大数部分(从max/2到max部分的数)比小数部分(min到max/2)的最大循环节长度大。所以有了下面的程序:
这里,我要写两点想法:第一,题目中说求数字i,j之间的最大循环节长度,但是样例输入却都是按min,max的顺序给出,这让我们产生了一种错觉:输入就是按较小数、较大数输入的,这也是我多次TL的原因。记住:当题目要求模棱两可的时候,一定要注意其真正的意思,不要带入自己的观念。第二,我列举了10以内数的循环节长度,发现相邻两个数中奇数较大时,奇数的循环节长度一般比偶数的大;但是如果偶数较大时,这个就不成立,因此,当一个范围的最大数是偶数的时候,要单独计算其循环节长度,剩下的就归结为前一类情况了,也就可以只计算奇数的循环节长度(这里是不严格的推广)。另外,一个范围(min到max)内的大数部分(从max/2到max部分的数)比小数部分(min到max/2)的最大循环节长度大。所以有了下面的程序:
#include<stdio.h> int main() { int min,max,min_o,max_o; int i,tmp,rst,count; char input[100]; while(gets(input))/*处理循环输入*/ { rst = 0; sscanf(input,"%d %d",&min_o,&max_o); if(max_o > min_o ) { min = min_o; max = max_o; } else { max = min_o; min = max_o; } if(max%2 == 0)/*单独处理偶数最大上限,下面只判断奇数*/ { count = 0; tmp = max; while(tmp != 1)/*处理最大数*/ { if(tmp%2 == 0) tmp /= 2; else tmp = tmp*3 + 1; count ++; } if(count > rst)/*记录最大数*/ rst = count; } tmp = max/2;/*范围的大数部分*/ if(tmp%2 == 0) tmp ++; if(tmp < min)/*修正范围*/ { if(min%2 == 0) tmp = min + 1; else tmp = min; } for(i = tmp;i <= max;i += 2)/*循环这个范围内的大数那部分*/ { tmp = i; count = 0; while(tmp != 1)/*处理每一个数*/ { if(tmp%2 == 0) tmp /= 2; else tmp = tmp*3 + 1; count ++; } if(count > rst)/*记录最大数*/ { rst = count; } } printf("%d %d %d\n",min_o,max_o,rst + 1);/*按输入的顺序输出i,j*/ } return 0; }
相关文章推荐
- hdoj2034
- oracle安装,远程连接,快速导入导出
- spark DataFrame用法
- linux查看电脑硬件配置
- Linq to Sql语法及实例大全
- IntelliJ IDEA 快捷键
- 信息安全
- killall命令
- 回到原点——UART
- mac os 用真机调试android应用
- 通过XHR API来下载和上传图片
- 容斥原理二进制实现
- Python写个简单的字符画转换程序
- POJ3279
- ceph-deploy搭建ceph集群
- 随想录(多学一点汇编语言)
- 扩展欧几里德原理
- Makefile模板
- hdu 5676 ztr loves lucky numbers(STL大法好)
- 公路乘车