探索合数世纪题解

探索合数世纪

问题描述

  若一个世纪的100年号中不存在一个素数,则称这个世纪为合数世纪。求第n个合数世纪(公元0年起始)。

输入描述

  输入n,为整数

输出描述

  输出合数世纪起始与结束年份,用空格隔开

样例输入

1

样例输出

1671800 1671899

  这道题是一道遍历题,遍历0-99,没有合数世纪就累加100,诀窍在于如何让代码的效率更好。

  我首先想到的是,用for循环对0到99进行素数判断,只要有一个素数就认为这个世纪不行,判断素数我用的代码如下

1 int judge(int n)
2 {
3     int sum=0;
4     for(int i=2;i<n/2;i++)
5     {
6         if(num%i==0)    return 0;
7     }
8     return 1;
9 }

  于是问题出现了,判断素数的代码上面这个已经是我能想到的效率最快的一个了,但还是不行,时间复杂度约为为O(n/2),随着n越大,循环次数越多,时间用得也越多,也就导致了,第一个合数世纪超过三秒还是判断不出来,我们以1秒的标准要求自己。

  查了一下资料,我发现了一个时间复杂度更低的算法。

  我原先是打算判断是不是素数,而我现在我打算判断是不是合数,代码如下

1 int judge(int n)
2 {
3     int sum=0;
4     for(int i=2;i*i<=n;i++)
5     {
6         if(n%i==0)  return 1;
7     }
8     return 0;
9 }

  很巧妙的一个判断是否是合数,时间复杂度为最大为O(n^0.5),远远小于O(n/2)。

  于是,我用这个算法打造了一个程序,如下

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int judgecompos(int n)    //在n~n+99之内进行素数累加
 5 {
 6     int count=0;
 7     for(int i=n+1;i<n+100;i+=2)    //省去偶数,节约时间
 8     {
 9         for(int j=2;j*j<=i;j++)
10         {
11             if(i%j==0)
12             {
13                 count++;    //合数累加
14                 break;
15             }
16         }
17     }
18     if(count==50)   return 1;
19     else    return 0;
20 }
21 
22 int main()
23 {
24     int begin=0,n=0;
25     cin>>n;
26     for(int i=1671700;;i+=100)    //这里取了一个巧,i从1671700开始,i从0开始也是没问题的
27     {
28         if(judgecompos(i)==1)
29         {
30             begin++;
31         }
32         if(n==begin)
33         {
34             cout<<i<<' '<<i++99<<endl;
35            break;
36         }
37     }
38     return 0;
39 }

  相比于原来的素数判断来说,这的是节省了很多时间,如果你有更好的代码和思路,欢迎交流!

原文地址:https://www.cnblogs.com/Conan-jine/p/12991411.html