PAT乙级1005

题目链接

https://pintia.cn/problem-sets/994805260223102976/problems/994805320306507776

题解

题意很简单,我并没有理解错,但刚开始最后一个测试点过不了。

代码逻辑检查多次后问了室友,说是isKey数组会越界,因为在callatz(n)中使用了isKey[n],这个n由于n=(3*n+1)/2导致n的范围变化,不再是小于100。

我真的呜了……

// PAT BasicLevel 1005
// https://pintia.cn/problem-sets/994805260223102976/problems/994805320306507776
#include 
#include 
using namespace std;

#define N 310        // 数组大小
bool isKey[N];       // N个数字是否为关键数:isKey[i]==true,则i是关键数;否则i不是关键数
bool isValid[N];     // N个数字是否被用户输入:isValid[i]==true,则i已被用户输入;否则i未被用户输入
void callatz(int n); // 循环处理isKey[n]:n若被覆盖,则不必往下计算,函数结束;若n未被覆盖,则覆盖n并按规则更新n。循环以上过程

int main()
{
    // 默认N个数字都未被覆盖,即N个数字是关键数
    fill(isKey, isKey + N, true);

    // 记录k个正整数n;对于每个正整数n,调用callatz()函数(用户输入的正整数n,并不会被自己覆盖,所以传参时直接将n更新)
    int k, n;
    scanf("%d", &k); // k个整数
    for (int i = 0; i < k; ++i)
    {
        scanf("%d", &n);
        isValid[n] = true; // 记录用户输入的正整数n
        callatz(n % 2 == 0 ? n / 2 : (3 * n + 1) / 2);
    }

    // 输出结果
    bool isFirstKey = true;
    for (int i = N - 1; i >= 0; --i)
    {
        if (isValid[i] && isKey[i])
        {
            if (isFirstKey)
            {
                printf("%d", i);
                isFirstKey = false; // 输出第一个关键数后,之后输出的关键数就不是第一个关键数了
            }
            else
            {
                printf(" %d", i);
            }
        }
    }

    system("pause");
    return 0;
}

void callatz(int n)
{
    while (n != 1)
    {
        // n未被覆盖
        if (isKey[n])
        {
            // 将n覆盖
            isKey[n] = false;

            // 按照规则更新n
            if (n % 2 == 0)
            {
                n = n / 2;
            }
            else
            {
                n = (3 * n + 1) / 2;
            }
        }
        // n已被覆盖,不必往下计算
        else
        {
            break;
        }
    }
}

作者:@臭咸鱼

转载请注明出处:https://www.cnblogs.com/chouxianyu/

欢迎讨论和交流!


你可能感兴趣的:(PAT乙级1005)