1. 程式人生 > >SXYBT-0102H數

SXYBT-0102H數

試題編號:2603 收 藏   
SXYBT-0102H數
難度級別:B; 執行時間限制:1000ms; 執行空間限制:65536KB; 程式碼長度限制:2000000B
試題描述

形如4n+1的數被稱為“H數”,乘法在“H數”組成的集合內是封閉的。在這個集合中只能被1和本身整除的數叫做“H-素數”(不包括1),其餘的數被稱為“H-合數”。一個“H-合成數”是一個能且只能分解成兩個“H-素數”乘積的“H-合數”(可能有多種分解方案)。比如441=21*21=9*49,所以441是“H-合成數”。125=5*5*5,所以125不是“H-合成數”。

求0到h範圍內“H-合成數”的個數。

輸入
輸入包含若干行,每行一個小於等於1000001的整數h,輸入0時表示結束。
輸出
對於每一行輸入,輸出一個數,表示答案。
輸入示例
21
85
0
輸出示例
0
5

洛谷題目傳送門:https://www.luogu.org/problem/show?pid=UVA11105


思路:主題思路應該是篩法吧,先篩特殊的H-素數,再通過素數找到H-合成數。我才不會告訴你我調了三個小時。

 提示:這是我們校內OJ,到洛谷上注意讀題目輸出要求。

直接上程式碼

 1 #include<bits/stdc++.h>
 2 #define MAXN 1000002
 3 using namespace std;
 4 int h;
 5 bool prime[MAXN],s[MAXN];
 6 void init(int n)//篩H-素數的函式 
 7 {
 8     for(int i=5;i<n/5;i+=4) 
 9     {
10         if(prime[i]==false)
11         {
12             for(int j=5;j*i<n;j+=4)
13             {
14                 prime[i*j]=true;
15             }
16         }
17     }  
18 }
19 
20 int main()
21 {
22     init(MAXN);
23     for(int i=5;i*i<MAXN;i+=4) //直接處理最大範圍內的H-合成數 
24     {
25         if(prime[i]==false)
26         {
27             for(int j=5;i*j<MAXN;j+=4) 
28             {
29                 if(prime[j]==false) s[i*j]=true;//通過H-素數推出H-合成數
30             }
31         }
32     }  
33     while(1)
34     {
35         int ans=0;
36         scanf("%d",&h);
37         if(h==0) break;
38         for(int i=5;i<=h;i+=4) 
39         {
40             if(s[i]==true) ans++;//直接走一遍就OK了 
41         }
42         printf("%d\n",ans);
43     }
44     return 0;
45 }
View Code