杭電 ACM Step Chapter Two Section 1
阿新 • • 發佈:2018-11-22
最小公倍數
- 兩個數的最小公倍數=兩個數的乘積/兩個數的最大公約數,即[a,b]=a*b/(a,b)。問題轉化成求最大公約數,這裡使用歐幾里得輾轉相除法求解。
#include <stdio.h>
#include <stdlib.h>
int gcd(int a,int b)//求兩個正整數的最大公約數
{
int r,t;
if(a<b) //保證a>b
{
t=a;
a=b;
b=t;
}
while(a%b !=0)
{
r=a%b ;
a=b;
b=r;
}
return b;
}
int main()
{
int a,b;
int lcm,g;
while(scanf("%d%d",&a,&b)!=EOF)
{
g=gcd(a,b);
lcm=(a*b)/g;
printf("%d\n",lcm);
}
return 0;
}
How many prime numbers
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int IsPrime(int a)
{
if(a<2) return 0;//小於2的數既不是素數也不是合數
for(int i=2;i<=sqrt(a);i++)
{
if(a%i==0) return -1;//能夠整除非1的某個數,說明是合數
}
return 1;//判斷為素數,返回1
}
int main()
{
int N;/*將輸入資料的個數*/
int a,sum;
while(scanf("%d",&N)!=EOF)
{
sum=0 ;
while(N--)
{
scanf("%d",&a);
if(IsPrime(a)==1) sum++;
}
printf("%d\n",sum);
}
return 0;
}
相遇週期
- 這道題中的相遇週期即兩個衛星各自週期的最小公倍數。所以問題轉化為求分數的最小公倍數問題。
- 解法:首先將分數化為最簡形式,然後求分子的最小公倍數作為分子,分母的最大公約數作為分母
- 注意點:資料型別有問題,剛開始寫好程式碼卻報錯,上網借鑑別人的程式碼,發現數據型別不是簡單的int型,輸入中給出的那一串\\\符號已經表明數字會很大,所以需要使用更長的資料型別。
#include <stdio.h>
__int64 _gcd(__int64 x,__int64 y)
{
__int64 r;
if(x<y)
{
__int64 temp=y;
y=x;
x=temp;
}
while(x%y !=0)
{
r=x%y;
x=y;
y=r;
}
return y;
}
__int64 main()
{
__int64 T;
__int64 a,b,c,d;
scanf("%I64d",&T);
__int64 m,n;
while(T--)
{
scanf("%I64d/%I64d%I64d/%I64d",&a,&b,&c,&d);
/*首先將分數化為最簡形式*/
m=_gcd(a,b);
a=a/m;
b=b/m;
n=_gcd(c,d);
c=c/n;
d=d/n;
m=_gcd(b,d);//對分母求最大公約數
n=_gcd(a,c);
n=(a*c)/n;//對分子求最小公倍數
if(n%m==0) printf("%I64d\n",n/m);
else printf("%I64d/%I64d\n",n,m);
}
return 0;
}
Largest prime factor
- 初始的思路是將範圍內所有的素數找出並儲存到陣列A中,然後對輸入的資料在A中尋找其最大素因子,其下標即所在位置,但是提交發現超時
- 後來借鑑網上思路,利用素數篩選法的思路解決問題
#include <stdio.h>
#include <math.h>
#define max 1000001
int LPF[max];/*注意非靜態變數陣列不能開的太大*/
int main()
{
for(int i=0;i<max;i++) LPF[i]=0;
int n,postion=0;//positon表示某個素數在素數表中的位置
LPF[1]=0;
for(int i=2;i<max;i++)
{
if(LPF[i]==0) //如果i還未被小於自身的任何素數整除,則確定i也是素數
{
postion++;
for(int j=i;j<max;j=j+i) LPF[j]=postion;
//所有是i的倍數的整數,LPF的值暫時為positon,不管更新,即得到最大素因子的位置
}
}
while(scanf("%d",&n) != EOF)
{
printf("%d\n", LPF[n]);
}
return 0;
}
又見GCD
#include <stdio.h>
int _gcd(int x,int y)
{
if(x<y)
{
int temp=y;
y=x;
x=temp;
}
int r=y;
while(x%y)
{
r=x%y;
x=y;
y=r;
}
return r;
}
int main()
{
int n;
int a,b,c;
scanf("%d",&n);
int max=10;
for(int i=2;i<7;i++) max=max*10;
while(n--)
{
scanf("%d%d",&a,&b);
c=2*b;
for(int i=3;c<max;i++)
{
if(_gcd(a,c)==b)
{
printf("%d\n",c);
break;
}
c=i*b;
}
}
return 0;
}
七夕節
#include <stdio.h>
int main()
{
int A[500005];
A[1]=0;
for(int i=2;i<500001;i++) A[i]=1;//大於1的數都有因子1
for(int i=2;i<500001;i++)
{
for(int j=2*i;j<500001;)
{
A[j]=A[j]+i;//記錄數j的因子和
j=j+i;
}
}
int T,N;
scanf("%d",&T);
while(T--)
{
scanf("%d",&N);
printf("%d\n",A[N]);
}
return 0;
}
找新朋友
- 尤拉函式:對於正整數n,尤拉函式就是小於或者等於n的數中與n互質的數的數目
- 通過百度可以得到尤拉函式的通式。根據通式編寫程式碼。
#include <stdio.h>
#define max 32768
int A[max];
void eular()
{
A[1]=1;
for(int i=2;i<max;i++) A[i]=i;
for(int i=2;i<max;i++)
{
if(A[i]==i)
{
for(int j=i;j<max;j=j+i)
A[j]=A[j]/i*(i-1);//尤拉通式
}
}
}
int main()
{
int CN,N;
eular();
scanf("%d",&CN);
while(CN--)
{
scanf("%d",&N);
printf("%d\n",A[N]);
}
return 0;
}