首页 > 其他分享 >牛客网一道素数问题

牛客网一道素数问题

时间:2023-04-11 22:57:58浏览次数:37  
标签:一道 int printf while 牛客 素数 ans 大佬

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

今天编出来的程序破天荒地达到了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;
}

标签:一道,int,printf,while,牛客,素数,ans,大佬
From: https://www.cnblogs.com/Hubugui/p/17308184.html

相关文章

  • LRU management (牛客多校) (map+list)
        思路:利用map+list暴力模拟就彳于了#pragmaGCCoptimize(2)#include<bits/stdc++.h>usingnamespacestd;#defineIOSios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);#defineMAXN100001#defineINF(0x3f3f3f3f)#defineuintunsignedint#d......
  • Magic Line (牛客多校) (贪心,构造)
    题目大意:在平面直角坐标系中有偶数个点,求两个点使这两个点的连线两边点的数量相同且不经过任何一个点点的坐标都为整数,且绝对值不大于1000思路:我们先对点按横坐标排序,找到中间的两个点,如果这两个点横坐标不同,可以在两点之间找一条平行于y轴的直线如果相同的,因为点的纵坐标不......
  • P1835 素数密度
    给定区间[L,R](1≤R<(1<<30) R−L≤1e6),请计算区间中素数的个数。筛出sqrt(R)的质数p,遍历L~R的数,看能否被p约分,也就是合数,打个标记 #include<iostream>#include<cstring>#include<cmath>#include<algorithm>usingnamespacestd;constintM=1e6+30;......
  • 牛客网一道题以及对我自己屎山代码的反思
    做这么个题,费了大劲,不是有什么地方不会需要去查,也不是没思路,而是纯粹的脑子糊涂。东一榔头西一棒槌,把握不住要点,这是做事方式的问题。这样写代码,绝对是第二天就看不懂的那种我写的141行屎山#include<stdio.h>#include<stdlib.h>/*明明生成了N个1到500之间的随机整......
  • 2023年牛客基础训练营2-I
    题目链接:https://ac.nowcoder.com/acm/contest/46810/I乱搞题,但是有一些差分思想在里面。先将所有的$$x_i都设置为第一个等级。注意到一个性质,不是所有的h都可以使答案发生变化。然后我们可以先求出所有可以使\(x_i\)发生变化的h的最小值,接着从小到大枚举所有h。所有\(x_i都会......
  • 牛客-华为研发工程师编程题
    过于简单,至少目前这样的题做来没有意义1.汽水瓶intmain(){ //这个获取输入就不太常规 vector<int>in; stringtemp; //读入失败getline会返回一个空 while(getline(cin,temp)&&temp!="0"){ in.push_back(stoi(temp)); } //最多只借一个瓶子,这样凑成3......
  • (5)使用函数验证哥德巴赫猜想:任何一个不小于6的偶数均可表示为两个奇和。输入两个正整数
    #include<stdio.h>#include<math.h>intprime(intm){  inti;  if(m<2)    return0;  for(i=2;i<=sqrt(m);i++){    if(!(m%i))      return0;  }  return1;}intmain(){  intm,n,flag;  printf("Enterm,......
  • 牛客小白月赛70
    A.小d和答案修改收获isupper函数。B.小d和图片压缩关键在于找到坐标的对应关系,或者将每个小方格加到左上角。C.小d和超级泡泡堂简单dfs。D.小d和孤独的区间只包含1个1的区间可以用总区间数减去2端的区间数,也可以直接由左端点的个数乘以右端点的个数得到。E.小d的博弈 博......
  • 利用网络准入把好企业网入网第一道关
     原创Grodd2018-10-2212:33:37博主文章分类:NetOps©著作权文章标签802.1x文章分类网络安全阅读数5113    最近完成了公司的准入项目,项目历时3个多月,部署点位将近上千个。在部署的过程中,也曾踩过各种各样的坑。公司采用某第三方软件系统作为准入控制平台。该套......
  • 【牛客小白月赛70】A-F题解【小d和超级泡泡堂】【小d和孤独的区间】【小d的博弈】【小
    比赛传送门:https://ac.nowcoder.com/acm/contest/53366难度适中。......