數論學習之起步篇(一)

來源:互聯網
上載者:User

1. 除法運算式(gcd法求最大公約數)

//給你一個除法運算式:X1/X2/X3/X4……/Xk//通過添加括弧,問能否得到整數//分析可得,只有X2是不能做分子的。題目就轉化為求一個分數能否為整數#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;int x[100];int gcd(int a, int b){    return b==0 ? a : gcd(b,a%b);   //gcd的遞迴層數不會超過4.75lgN + 1.6723,最大層數來自於gcd(Fn,Fn-1).其中Fn為斐波那契數列}int main (){    int i,j,k;    cin>>k;    for (i=1; i<=k; i++)        scanf("%d",x+i);    x[2]/=gcd(x[1],x[2]);    for (i=3; i<=k; i++)        x[2]/=gcd(x[2],x[i]);    if (x[2]==1) cout<<"YES"<<endl;    else cout<<"NO"<<endl;//    gcd(a,b) * lcm(a,b) = a * b;//    其中gcd(a,b)為最小公約數,lcm(a,b)為最大公倍數,//    在求最大公倍數時,用 lcm(a,b) = a / gcd(a,b) * b 以免溢出    return 0;}

2. 無平方因子的個數(素數篩選法的原理和應用)

//給出正整數n和m,區間[n,m]內的”無平方因子“的數有多少個?//整數p無平方因子若且唯若不存在k>1,使得p是k^2 的倍數。1 <= n <= m <= 10^12, m - n <= 10^7////素數篩選法:用vis[i]=1 來表示已經非素數//memset(vis,0,sizeof(vis));//for (int i = 2; i <= n; i++)//    if (!vis[i])//        for (j = i*2; j <= n; j+=i) vis[j]=1;//這個代碼的效率是O(nlogn)////素數篩選法改進,並且用prime數組記錄下素數////int m = sqrt(n+0.5);//int c = 0;//memset(vis,0,sizeof(vist));//for (int i = 2; i <= m; i++)//    if (!vis[i])//    {//        prime[c++]=i;//        for (j = i*i; j <= n; j+=i) vis[j]=1;//    }////素數定理:π(x)~x/ln(x)//////那這道題也可以用類似的想法來解決,對於不超過sqrt(m)的所有素數p,篩選掉區間[n,m]內p^2 的所有倍數#include<iostream>#include<cmath>#include<algorithm>#include<cstdio>#include<cstring>using namespace std;int vis[1000000],c=0;int prime[100000];void getprime(long long t){    int m = sqrt(t+0.5);    memset(vis,0,sizeof(vis));    for (int i=2; i<=m; i++)        if (!vis[i])        {            prime[c++]=i;            for (int j=i*i; j<=t; j+=i) vis[j]=1;        }}int map[11000000]={0};int main (){    long long n,m,t;    cin>>n>>m;    t=sqrt(m+0.5);    getprime(t);    for (int i = 0; i < c; i++)    {        long long st,ed;        st = n / prime[i] / prime[i];        ed = m / prime[i] / prime[i];        for (long long j = st; j <= ed; j++)        {            long long tmp;            tmp = j * prime[i] * prime[i];            map[tmp-n] = 1;        }    }    int sum = 0;    for (int i = 0; i <= m-n; i++)        if (!map[i])            sum++;    cout<<sum<<endl;}

3. 擴充歐幾裡得演算法

//直線上的點//求直線ax+by+c=0 上有多少個整點(x,y)滿足x∈[x1,x2],y∈[y1,y2]。////擴充歐幾裡得演算法,找出一對整數(x,y),使得ax+by=gcd(a,b)//遞迴實現: x1=y2; y1=x2-[a/b]*y2#include<iostream>#include<cstdio>#include<cmath>#include<algorithm>using namespace std;int x,y,d;void ex_gcd(int a,int b){    if (!b)    {        x=1;        y=0;        return ;    }    ex_gcd(b,a%b);    int t = x;    x = y;    y = t - (a/b)*y;}void ex_gcd(int a, int b, int &d, int &x, int &y){    if (!b)    {        d=a;        x=1;        y=0;    }    else    {        ex_gcd(b,a%b,d,y,x);        y -= (a/b)*x;    }}int main (){    int a,b;    cin>>a>>b;    ex_gcd(a,b);    cout<<x<<" "<<y<<endl;    ex_gcd(a,b,d,x,y);    cout<<x<<" "<<y<<endl;    return 0;}其中x,y是ax+by=gcd(a,b)的一組解,(x+kb',y-ka')為任意解若ax+by=c,其中c是gcd(a,b)的倍數,那麼有整數解,否則無整數解


相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.