1001. 害死人不偿命的(3n+1)猜想 (15)

来源:http://www.patest.cn/contests/pat-b-practise/1001
重点:循环条件控制,很容易出细微的逻辑错误。

#include<stdio.h>

int main() {
    int n = 0, hold = 0, i = 0, j = 0, k = 0, times = 0;
    int arr[105] = {0};
    scanf("%d", &n);
    for (i = 0; i < n; i++) {
        scanf("%d", &hold);
        arr[i] = hold;
    }

    for (i = 0; i < n; i++) { //遍历arr中每一个数
        j = arr[i];
        times = 0; // times是为了防止某个数覆盖的数太多,而后面一些所覆盖的数大于100的很多是无意义的。后面有说明。
        if (j == 0) continue;//0,说明已被覆盖,直接跳过。
        do {                 // 此个do-while循环是最多遍历50个没被覆盖的数所能覆盖的数,用times控制
            times++;
            if ((j&1) == 0)
                j >>= 1;
            else
                j = (3*j + 1)/2;
            for (k = 0; k < n; k++) {// 若arr中的某个数被覆盖了,令它为0
                if (arr[k] == j) {
                   arr[k] = 0;
                }                
            }

        }  while ((times < 50 ) || (j < 1000 && j > 1));//times超过49,或者j已经归1.跳出。由对arr[i]操作过到对arr[i+1]操作.!!!这里很重要,我之前debug了好久才发现是这里条件错了!!!!
    }

    for (i = 0; i < n - 1; i++) { //排序,为使结果降序输出
        for (j = n - 1; j > i; j--) {
            if (arr[j] > arr[j-1]) {
                hold = arr[j];
                arr[j] = arr[j-1];
                arr[j-1] = hold;
            }
        }
    }

    for (i = 0; i < n; i++) {// 按要求输出未被覆盖,即不为0的数。
        if (arr[i] != 0 && arr[i+1] != 0) {
            printf("%d ", arr[i]);
        } else if (arr[i] != 0 && arr[i+1] == 0){
            printf("%d", arr[i]);
            break;
        }
    }
    return 0;
}

对times控制的说明:

//从2100便利,找出这堆数所覆盖值的最大值,和每个数最多需要对j处理的次数的最大值
#include<stdio.h>

int main() {
    int j = 0 ,i = 0;
    long max = 0,times = 0,times_max = 0, max_max = 0;
    for (i = 2; i <= 100; i++) {
        max = 0;
        times = 0;
        j = i;
        do {
            if ((j&1) == 0) {
                j >>= 1;
            } else {
                j = (3*j + 1)/2;
            }
            times++;
            if (j > max) 
                max = j;
        }  while (j > 1);
        if (times > times_max)
            times_max = times;
        if (max > max_max)
            max_max = max;
    }
    printf("max:%ld\n", max_max);
    printf("times:%ld\n", times_max);
    return 0;
}

运行结果出乎意料。
结果图
这说明:原来我的times是不必要的。但是懒惰的博主不想删了。聪明的读者可以自行改良。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值