欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

菜鸟记

程序员文章站 2022-06-24 14:14:36
题目: 对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。 当我们验证卡拉兹猜想的时候,为了避免重复计算,可以记录下递推过程中遇到的每一个数。例如对 n=3 进行验证的时候,我们需要计算 3、5、8、4、2、1,则当我们对 n=5、8、4、2 进行验 ......

题目:

对任何一个正整数 n,如果它是偶数,那么把它砍掉一半;如果它是奇数,那么把 (3n+1) 砍掉一半。

 

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

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

 

思路:

一开始是没有清晰的思路的,在纸上做下草稿,发现关键的点在于如何判定覆盖以及判定覆盖后怎样进行处理?那就用一个很笨的办法

1.设定一个数组用来存放每个数验证时所需计算的数字,然后将其和已知数列一一比较

2.比较过后将原数列中被覆盖的数置零,从这点又引申出来的想法是在第一层循环中加入if判定是否为零,若为零可直接跳过比较,这样也省去了不必要的步骤

递推过程函数较为简单,传入n(给定数列的个数),比较数组(copy[]),返回值为int,即递推过程中的数的个数

int callatz(int n,int copy[]){

    int i = 0;

    do{

        if(n%2==0)  n = n/2;

        else n = (n*3+1)/2;

        copy[i++] = n;

    }while (n!=1);

    i = i-1;

    return i;

}

 

 

主函数,题目要求是将结果从大到小顺序输出,那首先要把它们找出来放到数组里,用循环来搞定

 

 

   int n;

    (void)scanf("%d",&n);

    int str[n];//存放已知数列

    int copy[size];//存放递推过程里的数

    for(int i = 0;i < n;i++){

        (void)scanf("%d",&str[i]);

    }

    for(int y = 0;y < n;y++){

        if(str[y]!=0){//判定是否为零,为零说明该数已被覆盖

            int size = callatz(str[y], copy);//递推过程中数的个数

    //开始和已知数列比较,同时更新已知数列

            for(int i = 0;i < size;i++){

                for(int z = 0;z < n;z++){

                    if(str[z]==copy[i])

                        str[z] = 0;

                }

            }

        }        

    }

 

然后定义一个新数组存放结果,进行排序然后输出

  

    int z = 0;

    int new[n];

    for(int i = 0;i < n;i++){

        if(str[i]!=0)

            new[z++] =str[i];

    }

   //排序 最简单的选择排序....

    int min = 0,temp;

    

    for(int i = 0;i < z-1;i++){

        temp = i;

        for(int j = i+1;j <z;j++){

            if(new[j] > new[temp]){

                temp = j;

            }

        }

        min = new[i];

        new[i] = new[temp];

        new[temp] = min;

    }

    int i = 0;

    for(i = 0;i < z-1;i++){

        printf("%d ",new[i]);

    }

    printf("%d",new[z-1]);

    printf("\n");//输出格式的要求

 

 

因为排序出了错而报错了,要重新好好研究一下排序了...基本功太汗颜了