zoukankan      html  css  js  c++  java
  • 1005 继续(3n+1)猜想

    15分题

    卡拉兹(Callatz)猜想:

    对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。这样一直反复砍下去,最后一定在某一步得到 n=1。卡拉兹在 1950 年的世界数学家大会上公布了这个猜想,传说当时耶鲁大学师生齐动员,拼命想证明这个貌似很傻很天真的命题,结果闹得学生们无心学业,一心只证 (3n+1),以至于有人说这是一个阴谋,卡拉兹是在蓄意延缓美国数学界教学与科研的进展……

    我们今天的题目不是证明卡拉兹猜想,而是对给定的任一不超过 1000 的正整数 n,简单地数一下,需要多少步(砍几下)才能得到 n=1?

    实际是
    递归 的思想,这题有点简单,代码如下:

    #include <stdio.h>
    
    int CA_thinking(int n, int i){
    	if(n!=1){
    		i++;
    		if(n%2==0){
    			CA_thinking(n/2,i);
    		}else{
    			CA_thinking((3*n+1)/2,i);
    		}
    	}else{
    		return i;
    	}
    }
    
    void main(){
    	int n,result;
    	scanf("%d",&n);
    	result=CA_thinking(n,0);
    	printf("%d
    ",result);
    }
    
    

    25分题

    继续(3n+1)猜想

    卡拉兹(Callatz)猜想已经在1001中给出了描述。在这个题目里,情况稍微有些复杂。

    当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n=3 进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对 n=5、8、4、2 进行验证的时候,就可以直接判定卡拉兹猜想的真伪,而不需要重复计算,因为这 4 个数已经在验证3的时候遇到过了,我们称 5、8、4、2 是被 3“覆盖”的数。我们称一个数列中的某个数 n 为“关键数”,如果 n 不能被数列中的其他数字所覆盖。

    现在给定一系列待验证的数字,我们只需要验证其中的几个关键数,就可以不必再重复验证余下的数字。你的任务就是找出这些关键数字,并按从大到小的顺序输出它们。

    /*
    分析
    input
    	6  ------------K (<100)
    	3 5 6 7 8 11  n -----------(1<n≤100)
    -----------------------------
    	(3 5 8 4 2 1)
    	(5 (8 4 2 1))
    	6 (3 5 8 4 2 1)
    	7 (11 17 26 13 20 10 (5 8 4 2 1))
    	(8 4 2 1)
    	(11 17 26 13 20 10 5 8 4 2 1)
    ------------------------------
    output 7 6
    ------------------------------
    	追溯问题,可以观察到括号中的数是重复的,而output中7 6只出现一次,即 - 根数字
    	所以用tag[101]数组标记递归过程中出现的数字出现的次数,初始化为0	
    */
    
    #include<iostream>
    #include <algorithm> //C++从大到小排序sort---步骤1
    using namespace std;
    
    //C++从大到小排序---步骤2
    bool cmp(int a,int b){
    	return a > b; //从小到大a<b
    }
    
    int main(){
    	int num,i;
    	int tag[101] = {0},a[101],res[101], t,temp;
    	cin >> num;
    
    	for(i = 0; i < num; i++){
    		cin >> a[i];
    		temp = a[i];
    		if(temp == 1){    
    			tag[temp] ++ ;
    		}else{
    			while(temp!=1){
    				if(temp<=100){	
    					//这里需要判断一下,不然会出现段错误,即在递归的过程中会出现大于100的数,
    					//但是输入的数在[1,100]区间,所以不用管那些大于100的数,我们需要的是在输入的数中找本源
    					tag[temp]++;
    				}
    				if(temp%2 == 0){
    					temp = temp/2;
    				}else{
    					temp = (temp*3+1)/2;
    				}
    			}
    		}
    	}
    	int sum = 0,j = 0;;
    	for(i = 0; i < num; i++ ){
    		t = a[i];
    		if(tag[t] == 1){
    			res[j++] = t;
    			sum++;
    
    		}
    	}
    	sort(res,res+j,cmp);//C++从大到小排序---步骤3
    	for(i = 0; i < j; i++ ){
    		cout << res[i];
    		if(i<j-1){
    			cout <<" ";
    		}
    	}
    }
    
  • 相关阅读:
    安装lnmp 时如何修改数据库数据存储地址及默认访问地址
    ubuntu 设置root用户密码并实现root用户登录
    解决ubuntu 远程连接问题
    linux 搭建FTP服务器
    PHP 根据ip获取对应的实际地址
    如何发布自己的composer包
    使用composer安装composer包报Your requirements could not be resolved to an installable set of packages
    laravel 框架配置404等异常页面
    使用Xshell登录linux服务器报WARNING! The remote SSH server rejected X11 forwarding request
    IoTSharp 已支持国产松果时序数据库PinusDB
  • 原文地址:https://www.cnblogs.com/tanghm/p/12518653.html
Copyright © 2011-2022 走看看