根据uva onlinejudge,3n + 1错误答案

时间:2016-10-20 14:03:28

标签: c onlinejudge

我正在尝试解决“3n + 1”问题并在uva onlinejudge上提交,但每次它说我的代码给出了错误的答案,不幸的是我找不到它的问题 这是一个问题:Problem 100

我的代码:

        #include <stdio.h>
        int main()
        {
            unsigned long int n, m;
            int max = 0;
            scanf("%d %d", &n, &m);

            int i;
            for (i = n; i <m + 1; i++)
            {
                int ter = i;
                int counter = 1;
                while (ter != 1)
                {
                    counter++;

                    if (ter % 2 == 1) { ter = 3 * ter + 1; }

                    else
                        ter = ter / 2;

                    if (ter == 1)
                        if (counter>max) { max = counter; }
                }
            }

            printf("%d %d %d\n", n, m, max);

            return 0;
        }

4 个答案:

答案 0 :(得分:1)

问题很明显。您没有按照问题陈述中的说明进行操作

  

对于任何两个数字i和j,您将确定最大循环   i和j之间所有数字的长度。

  

输入将包含一系列整数i和j,一个   每行一对整数。所有整数将小于1,000,000   并且大于0。

  1. 您只阅读了一行输入并打印了答案
  2. 您认为i小于j

答案 1 :(得分:0)

正确解决方案:

#include <stdio.h>

int cycleSize(int x) {
int cycle = 1;

while (x != 1) {
    if (x % 2 == 0) { //if even
        x = x / 2;
    } else { //if odd
        x = x * 3 + 1;
    }
    ++cycle;
}
return cycle;
}

int maxCycleSizeBetween(int a, int b) {
if (a > b) { //if b > a, swap them
    int temp = a;
    a = b;
    b = temp;
}
int maxCycle = 0;

for (; a <= b; a++) {
    int thisCycleSize = cycleSize(a);
    if (thisCycleSize > maxCycle) {
        maxCycle = thisCycleSize;
    }
}
return maxCycle;
}

int main() {
int a, b; //input vars

while (scanf("%d %d", &a, &b) != EOF) {
    printf("%d %d %d\n", a, b, maxCycleSizeBetween(a, b));
}
return 0;
}

答案 2 :(得分:0)

以下代码实现了要求

然而,一些在线代码竞赛预计会有一个最后的空白行。您需要确定这些细节。

#include <stdio.h>

int main( void )
{
    size_t n1;
    size_t m1;
    char buffer[1024];

    while( fgets( buffer, sizeof(buffer), stdin ) )
    {
        if( 2 != sscanf(buffer, "%lu %lu", &n1, &m1) )
        {
            break;
        }

        size_t n = n1;
        size_t m = m1;

        if( n1 > m1 )
        { // then first number greater than second so reverse for calculations
            size_t temp = n;
            n = m;
            m = temp;
        }

        size_t maxCount = 0;
        for (size_t i = n; i <= m; i++)
        {
            size_t ter = i;
            size_t counter = 1;

            while (ter != 1)
            {
                counter++;

                if ( (ter & 0x01) == 1) 
                {  // then odd
                    ter = 3 * ter + 1; 
                }

                else
                { // else even
                    ter = ter / 2;
                }

                // for testing only
                // printf( "%lu: %lu, %lu\n", counter, i, ter );
            }

            if( maxCount < counter )
            {
                maxCount = counter;
            }
        }

        printf("%lu %lu %lu\n", n1, m1, maxCount);
    }
}

注意:

  1. 如果输入非数字值,此代码将退出
  2. 如果遇到EOF,此代码将退出 - 这是预期的
  3. 如果输入的是负数,则此代码将失败;比赛规定说数字将在1 ... 1000000范围内,因此无需检查负数
  4. 如果输入行上只有一个数字,则此代码将退出
  5. 如果只输入<cr>,则此代码将退出

答案 3 :(得分:0)

以下函数执行请求的计算:

void n3plus1(int min, int max)
{
    int i, n, len, lenmax=0;

    for (i=min; i<=max; i++)
    {
        n= i; len= 1;
        while (n!=1) {
            if (n&1)
                 n= 3*n + 1;
            else n= n/2;
            len++;
        }
        if (len>lenmax) lenmax= len;
    }
    printf("Answer: %d %d %d\n", min,max,lenmax);
}

通过以下测试:

void test(void)
{
    n3plus1(22, 22);
    n3plus1(1, 10);
    n3plus1(100, 200);
    n3plus1(201, 210);
    n3plus1(900, 1000);
}

输出是:

Answer: 22 22 16
Answer: 1 10 20
Answer: 100 200 125
Answer: 201 210 89
Answer: 900 1000 174

注意:问题陈述中的“ i和j 之间所有数字的最大循环长度”必须解释为包括ij

代码假定输入为i<=j。该代码不包括阅读输入。