藍橋杯——趣味素數問題(2017.2.3)
阿新 • • 發佈:2019-02-01
一、基本素數問題回顧
1. 求給定範圍start~end之間的所有素數(1<=start<end)
原始碼:
程式截圖:#include <stdio.h> #include <math.h> int main() { int start,end; int i,j,k,num,flag; while(scanf("%d %d",&start,&end)!=EOF) { num=0; for(i=start;i<=end;i++) { k=sqrt(i); flag=1; for(j=2;j<=k;j++) { if(i%j==0) { flag=0; break; } } if(flag==1) //此處寫 j>=k+1 亦可 { num++; printf("%d ",i); if(num%10==0) printf("\n"); } } printf("\n%d~%d之間的素數個數為%d\n",start,end,num); } return 0; }
2. 輸入一個正整數n,判斷該數是否為素數
原始碼:
#include <stdio.h> #include <math.h> int is_Prime(int n) { int i; int flag=1; for(i=2;i<=sqrt(n);i++) { if(n%i==0) { flag=0; break; } } return flag; } int main() { int n; while(scanf("%d",&n)!=EOF) { if(is_Prime(n)) printf("%d是素數\n",n); else printf("%d不是素數\n",n); } return 0; }
程式截圖:
3. 輸入一個正整數n,輸出第n個素數(n<=10000)
原始碼:
#include <stdio.h> #include <math.h> #define maxn 100000 void Prime(int prime[],int n) { int i,j,k; int flag,t=0; int low,high,mid; for(i=2;i<=150000;i++) { k=sqrt(i); flag=1; for(j=2;j<=k;j++) { if(i%j==0) { flag=0; break; } } if(flag==1) prime[t++]=i; } low=0,high=t-1; //因素數陣列較大,用折半查詢法素數陣列下標,若下標+1=n,則輸出對應第n個素數 while(low<=high) { mid=(low+high)/2; if(mid==n) { printf("第%d個素數是:%d\n",n,prime[n-1]); break; } else if(mid<n) low=mid+1; else high=mid-1; } printf("\n"); } int main() { int n,prime[maxn]={0}; while(scanf("%d",&n)!=EOF) Prime(prime,n); return 0; }
程式截圖:
二、哥德巴赫猜想
輸入2000以內不小於4的正偶數n,將其分解為兩個素數之和(即驗證哥德巴赫猜想對2000以內的正偶數恆成立)
原始碼:
#include <stdio.h>
#include <math.h>
#define maxn 2000
void Split(int prime[],int n) //正偶數分解
{
int i,j,k;
int num=0,flag;
for(i=2;i<=2000;i++)
{
k=sqrt(i);
flag=1;
for(j=2;j<=k;j++)
{
if(i%j==0)
{
flag=0;
break;
}
}
if(flag==1)
prime[num++]=i;
}
for(i=0;i<num;i++) //表示為兩個素數之和,且前者小於後者
{
for(j=0;j<num;j++)
{
if(n==prime[i]+prime[j] && prime[i]<=prime[j])
printf("%d=%d+%d\n",n,prime[i],prime[j]);
}
}
}
int main()
{
int n,prime[maxn]={0};
while(scanf("%d",&n)!=EOF)
Split(prime,n);
return 0;
}
程式截圖:
另:控制不只一組解的情況下,輸出第一個素數最小的那組解
原始碼:
#include <stdio.h>
#include <math.h>
#define maxn 2000
void Split(int prime[],int n)
{
int i,j,k;
int num=0,flag,ok;
for(i=2;i<=2000;i++)
{
k=sqrt(i);
flag=1;
for(j=2;j<=k;j++)
{
if(i%j==0)
{
flag=0;
break;
}
}
if(flag==1)
prime[num++]=i;
}
for(i=0;i<num;i++)
{
for(j=0;j<num;j++)
{
ok=0; //輸出一組解的標誌
if(n==prime[i]+prime[j] && prime[i]<=prime[j]) //發現符合要求的一組解,輸出之,並將ok標誌置為1
{
printf("%d=%d+%d\n",n,prime[i],prime[j]);
ok=1;
}
if(ok==1) //隨後不在查詢其他符合要求的解,直接跳出內外層迴圈
break;
}
if(ok==1)
break;
}
}
int main()
{
int n,prime[maxn]={0};
while(scanf("%d",&n)!=EOF)
Split(prime,n);
return 0;
}
程式截圖:
三、可逆素數
從小到大輸出所有4位數的可逆素數
可逆素數是指:一個素數將其各位數字的順序倒過來構成的反序數也是素數
原始碼:
#include <stdio.h>
#include <math.h>
int is_Prime(int n)
{
int i;
int flag=1;
for(i=2;i<=sqrt(n);i++)
{
if(n%i==0)
{
flag=0;
break;
}
}
return flag;
}
int main()
{
int i,j,wei;
int reversenum,num=0;
for(i=1000;i<=9999;i++)
{
if(is_Prime(i))
{
j=i,wei=1000,reversenum=0;
while(j>0) //求一個數的“反序數”,如1234->4321
{
reversenum+=((j%10)*wei);
j/=10;
wei/=10;
}
if(is_Prime(reversenum))
{
printf("%d -- %d ",i,reversenum);
num++;
if(num%4==0) //控制每輸出4組數換一行
printf("\n");
}
}
}
return 0;
}
程式截圖:
四、迴文素數
求出所有不超過1000的迴文素數
迴文素數是指:一個整數n,其為素數,且從左向右和從右向左讀數值都相同
原始碼:
#include <stdio.h>
#include <math.h>
int is_Prime(int n)
{
int i;
int flag=1;
for(i=2;i<=sqrt(n);i++)
{
if(n%i==0)
{
flag=0;
break;
}
}
return flag;
}
int main()
{
int i,t,reversenum;
for(i=1;i<=9999;i++)
{
reversenum=0;
t=i;
while(t>0) //求"反序數"
{
reversenum=reversenum*10+t%10;
t/=10;
}
if(is_Prime(i)) //i為素數
{
if(i==reversenum) //且i從左向右和從右向左數值相同,輸出i
printf("%d\n",i);
}
}
return 0;
}
程式截圖:
五、孿生素數
求出m~n之間(包括m和n)的孿生素數,用(x,x+2)的形式表示
孿生素數是指:間隔為2的兩個相鄰素數(如(1,3),(3,5),(11,13)等)
原始碼:
#include <stdio.h>
#include <math.h>
int is_Prime(int n)
{
int i;
int flag=1;
for(i=2;i<=sqrt(n);i++)
{
if(n%i==0)
{
flag=0;
break;
}
}
return flag;
}
int main()
{
int i,m,n;
while(scanf("%d %d",&m,&n)!=EOF)
for(i=m;i<=n;i++)
{
if(is_Prime(i) && is_Prime(i+2))
printf("(%d,%d)\n",i,i+2);
}
return 0;
}
程式截圖:
六、梅森素數
求出指數為n(n<20)的所有梅森素數
梅森素數是指:形如 2^n-1 的正整數,其中指數n是素數,且 2^n-1 也是素數
原始碼:
#include <stdio.h>
#include <math.h>
int is_Prime(int n)
{
int i;
int flag=1;
for(i=2;i<=sqrt(n);i++)
{
if(n%i==0)
{
flag=0;
break;
}
}
return flag;
}
int main()
{
int i,j,n;
while(scanf("%d",&n)!=EOF)
{
for(i=1;i<=n;i++)
{
j=pow(2,i)-1;
if(is_Prime(i) && is_Prime(j))
printf("pow(2,%d)=%d\n",i,j);
}
}
return 0;
}
程式截圖: