牛客网一道素数问题

发布时间 2023-04-11 22:56:04作者: 针眼画师

我收回昨天的话,浪费时间或许不是能力问题,但是写出屎山,真真正正是能力问题

今天编出来的程序破天荒地达到了34ms,然而大佬们都是1ms,于是点开大佬们的代码查看,发现他们的写法,他们使用的算法,寥寥几行代码,我看了半天不得其义,尝试着运行,非常流畅,让人目瞪口呆。

多看一些代码之后,发现写法上是各有各的写法,但是算法却是大同小异,也就是说有“套路”可循,而不是现编。

这个是需要积累的,要多看大佬写的代码,不能自顾自的沉浸于制造屎山,如同闭关锁国,制造屎山而不自知。

尤其要学会那些涉及较广的,比如常有排序题,还有素数题,那么可以看看大佬们常用什么算法,也跟着用就是了,看大佬们有怎样的书写习惯,也跟着学就是了,要主动接纳好东西。

我的屎山代码
#include <stdio.h>
/*
功能:输入一个正整数,按照从小到大的顺序输出它的所有质因子(重复的也要列举)(如180的质因子为2 2 3 3 5 )数据范围: 1≤n≤2×10^9 +14 
*/
// 输入一个整数
// 按照从小到大的顺序输出它的所有质数的因子,以空格隔开。

// 判断是否素数 ,加速版
int isprime(int a) {
    // 判断器
    int key = 0;
    // 该数字不是97以内素数的倍数,所以检索范围缩小到 101~a-1
    for (int j = 101; j <= a - 1; j++) {
        // 能整除,不是素数,跳出循环
        if (a % j == 0) {
            break;
        }
        // 该数字不是97以内素数的倍数,所以不用遍历所有数,到a/97+1都不能整除,是素数
        if (j >= a / 97 + 1) {
            key = 1;
            break;
        }
    }
    return key;
}
// 对于不是素数的复杂数字寻找素数因子
void not_prime(int a) {
    // 重做main函数那一套,只不过排除了素数
    while (a != 1) {
        // 换除数挨个除
        for (int j = 2; j <= a - 1; j++) {
            // 能整除,判断是否素数,如果是,输出
            if (a % j == 0) {
                // 除数是素数就用来除 ,输出,然后退出for循环
                if (isprime(j) == 1) {
                    a = a / j;
                    printf("%d ", j);
                    break;
                }
            }
            // 如果a找不到可以除的,判断是否素数(基本就是),输出 ,结束
            if (isprime(a) == 1) {
                printf("%d ", a);
                a = 1;
            }
        }
    }
}

int main() {
    // 存放100以内素数的数组
    int primes[] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97};
    // 存放输入数字的数组
    int ans = 0;       // ------->注意数字小于2000000014,如果大于它,会变成其他数字,这涉及有符号整型的储存方式
    // 接收输入的数据
    scanf("%d", &ans);

    // 快速检查哪些素数是它的因子
    while (ans != 1) {
        // 素数表里的数挨个除
        for (int i = 0; i < 25; i++) {
            // 能除尽的输出,然后走下一轮
            if (ans % primes[i] == 0) {
                ans = ans / primes[i];
                printf("%d ", primes[i]);
                break;
            }
            // 除不尽的调用子函数,判断是不是素数
            if (i == 24) {
                // 是素数直接输出
                if (isprime(ans) == 1) {
                    printf("%d ", ans);
                    ans = 1;
                } else
                    // 不是素数在子函数中完成后续
                {
                    not_prime(ans);
                    ans = 1;
                }
            }
        }
    }
    return 0;
}
第一名大佬的代码
#include <stdio.h>
  
int main(void)
{
    int n;
    while(scanf("%d", &n) == 1)
	{
        int tmp = n;
        for(int i = 2; i * i <= tmp && n >= i; i++)
		{
            while(n % i == 0)
			{
                printf("%d ", i);
                n /= i;
            }
        }
        if(n - 1) printf("%d ", n);
        putchar('\n');
    }
    return 0;
}