考研机试第一天

1.素数(质数)筛法

问题1:给定一个数n,要求判断其是否为素数(0,1,负数都是非素数)

  #include<stdio.h>    
  #include<math.h>   
  bool judge(int x){
       if(x<1)    return false;
       int bound = (int)sqrt(x) + 1; //计算枚举上界,多枚举一个也不能少枚举一个数**
       for(int i = 2;i<bound;i++){
          if(x%i == 0)   return false;
       }
       return true;
   }   
 int main(){
          int x;
          while(scanf("%d",&x)!= EOF){
                puts(judge(x) ? "yes" : "no");
           }
           return 0;   
  }    
  注意:在上例中,sqrt()strlen()一样是比较耗时的函数之一,先将sqrt(n)+1赋值给bound,再进行循环可减少比较次数。

问题2:给定一个整数n(2<=n<=10000),要求输出所有从1到这个整数之间(不包括1和这个整数)个位为1的素数,如果没有则输出-1(素数之间用空格隔开,最后一个素数没有空格)

#include<stdio.h>
int prime[10000];   //保存筛得的素数
int primeSize;        //保存素数的个数
bool mark[10001]; //mark[x]为true才表示该数x被标记为非素数
void init(){
       for(int i=1;i <= 1000;i++){     //初试所有数字均未被标记
            mark[i] = false;
        }
        primeSize = 0;
        for(int i = 2;i <= 10000;i++){
             if(mark[i] == true) continue;
             else prime[primeSize++] = i;    //若未被标记,则得到一个新的素数
             for(int j = i*i;j<=10000;j+=i){  //直接从i*i开始算起,而不是2*i,可避免重复操作
                  mark[j] = true;
             }
        }
   }
   int main(){
       init();
       int n;
       while(scanf("%d",&n)!=EOF){
               bool isOutput = false;
               for(int i = 0;i<primeSize;i++){
                    if(prime[i]<n && prime[i] % 10 ==1){  //测试得到的素数是否符合条件
                        if(isOutput == false){            //如果为第一个,则该数之前不用添加空格
                             isOutput = true;
                             printf("%d",primep[i]);
                         }
                         else printf(" %d",prime[i]);    //否则在输出这个数字前输出空格
                     }
                }
                if(isOutput == false){    //如果不存在符合条件的数字
                   printf("-1\n");
                }
                else printf("\n");
            }
            return 0;
     }

2.分解素因数(质因数)

问题3:求正整数N(1<N<10^9)的质因数个数,相同的质因数需要重复计算。如120=2 *2 *2 *3 *5,共有5个质因数

#include<stdio.h>
int prime[100001];   //保存筛得的素数
int primeSize;        //保存素数的个数
bool mark[100001];    //mark[x]为true才表示该数x被标记为非素数
void init(){
       for(int i=1;i <= 1000;i++){     //初试所有数字均未被标记
            mark[i] = false;
        }
        primeSize = 0;
        for(int i = 2;i <= 100000;i++){
             if(mark[i] == true) continue;
             else prime[primeSize++] = i;    //若未被标记,则得到一个新的素数
             for(int j = i*i;j<=100000;j+=i){  //直接从i*i开始算起,而不是2*i,可避免重复操作
                  mark[j] = true;
             }
        }
   }
     int main(){
       init();
       int n;
       while(scanf("%d",&n)!=EOF){
            int ansPrime[30];  //按顺序保存被分解出来的素因数
            int ansSize=0;     //分解出来素因数个数
            int ansNum[30];    //保存被分解出的素因数对应的幂指数
            for(int i = 0;i<primeSize;i++){
               if(n%prime[i] == 0){
                  ansPrime[ansSize] = prime[i];   //该数为素因数
                  ansNume[ansSize] = 0;  //初始化幂指数为0
                  while(n%prime[i] == 0){ //分解出幂指数
                       ansNum[ansSize]++; //统计幂指数
                       n/=prime[i];
                  }
                  ansSize++;
                  if(n==1) break;
                }
             }
             if(n!=1){//若测试完仍未被分解至1,则剩余的因数一定是n个大于100000的素因数
               ansPrime[ansSize] = n;//记录该大素因数
               ansNum[ansSize++] = 1;//其幂指数只能为1
             }
             int ans = 0;
             for(int i = 0;i<ansSize;i++){
                ans+=ansNum[i];
              }
             printf("%d\n",ans);
           }
        return 0;
     }              
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值