日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

一本通1627【例 3】最大公约数

發布時間:2025/5/22 编程问答 21 豆豆
生活随笔 收集整理的這篇文章主要介紹了 一本通1627【例 3】最大公约数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1627:【例 3】最大公約數

時間限制: 1000 ms ??? ??? 內存限制: 524288 KB

【題目描述】

給出兩個正整數?A,B,求它們的最大公約數。

【輸入】

輸入共兩行,第一行一個正整數?A,第二行一個正整數?B。

【輸出】

在第一行輸出一個整數,表示?A,B?的最大公約數。

【輸入樣例】

18 24

【輸出樣例】

6

【提示】

數據范圍與提示:

對于 60% 的數據,1≤A,B≤1018

對于 100% 的數據,1≤A,B≤103000?。

?

sol:Super Gcd,高精。。。

直接輾轉相除肯定優秀到爆炸,所以我們選擇輾轉相減

然而直接輾轉相減肯定也是優秀到爆炸但是這道題特別水的數據居然讓我過了,這還說什么。。。

對于輾轉相減有一個優化,就是對于當前兩個數,如果一奇一偶,就把偶數除以2,如果兩個偶,就都除以2,把答案*2,如果兩奇就輾轉相減。

#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() {ll s=0;bool f=0;char ch=' ';while(!isdigit(ch)){f|=(ch=='-'); ch=getchar();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) {if(x<0){putchar('-'); x=-x;}if(x<10){putchar(x+'0'); return;}write(x/10);putchar((x%10)+'0');return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') inline void Read_S(char *S) {int Len=0;char ch=' ';while(!isdigit(ch)){ch=getchar();}while(ch=='0'){ch=getchar();}while(isdigit(ch)){S[++Len]=ch; ch=getchar();}return; } const int N=3005; const int Base=10000,Power=4; char SX[N],SY[N]; struct BigNum {int a[N];BigNum(){memset(a,0,sizeof a);}BigNum(char *S){memset(a,0,sizeof a);int i,bb,Pos=0,Len=strlen(S+1);a[0]=(Len-1)/Power+1;for(i=1;i<=Len;i++){if((i-1)%Power==0){Pos++; bb=1;}a[Pos]+=bb*(S[i]-'0');bb*=10;}}inline void Print(){write(a[a[0]]);int i;for(i=a[0]-1;i>=1;i--){if(a[i]<1000) putchar('0');if(a[i]<100) putchar('0');if(a[i]<10) putchar('0');write(a[i]);}}#define P(x) x.Print(),putchar(' ')#define Pl(x) x.Print(),putchar('\n') }X,Y; inline bool operator<(const BigNum &p,const BigNum &q) {if(p.a[0]!=q.a[0]) return p.a[0]<q.a[0];int i;for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i]){return p.a[i]<q.a[i];}return false; } inline bool operator==(const BigNum &p,const BigNum &q) {if(p.a[0]!=q.a[0]) return false;int i;for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i]){return false;}return true; } inline BigNum operator-(const BigNum &p,const BigNum &q) {int i;BigNum ans=p;for(i=1;i<=q.a[0];i++){ans.a[i]-=q.a[i];if(ans.a[i]<0){ans.a[i]+=Base;ans.a[i+1]--;}}while((!ans.a[ans.a[0]])&&ans.a[0]) ans.a[0]--;return ans; } int main() {freopen("data.in","r",stdin);freopen("my.out","w",stdout);Read_S(SX);reverse(SX+1,SX+strlen(SX+1)+1);X=BigNum(SX);Read_S(SY);reverse(SY+1,SY+strlen(SY+1)+1);Y=BigNum(SY);while(!(X==Y)){BigNum p,q;if(X<Y){p=Y;q=X;}else{p=X;q=Y;}X=q;Y=p-q;}Pl(X);return 0; } 意外水過的輾轉相減 #include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() {ll s=0;bool f=0;char ch=' ';while(!isdigit(ch)){f|=(ch=='-'); ch=getchar();}while(isdigit(ch)){s=(s<<3)+(s<<1)+(ch^48); ch=getchar();}return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) {if(x<0){putchar('-'); x=-x;}if(x<10){putchar(x+'0'); return;}write(x/10);putchar((x%10)+'0');return; } #define W(x) write(x),putchar(' ') #define Wl(x) write(x),putchar('\n') inline void Read_S(char *S) {int Len=0;char ch=' ';while(!isdigit(ch)){ch=getchar();}while(ch=='0'){ch=getchar();}while(isdigit(ch)){S[++Len]=ch; ch=getchar();}return; } const int N=3005; const int Base=10000,Power=4; char SX[N],SY[N]; struct BigNum {int a[N];BigNum(){memset(a,0,sizeof a);}BigNum(char *S){memset(a,0,sizeof a);int i,bb,Pos=0,Len=strlen(S+1);a[0]=(Len-1)/Power+1;for(i=1;i<=Len;i++){if((i-1)%Power==0){Pos++; bb=1;}a[Pos]+=bb*(S[i]-'0');bb*=10;}}inline void Print(){write(a[a[0]]);int i;for(i=a[0]-1;i>=1;i--){if(a[i]<1000) putchar('0');if(a[i]<100) putchar('0');if(a[i]<10) putchar('0');write(a[i]);}}#define P(x) x.Print(),putchar(' ')#define Pl(x) x.Print(),putchar('\n') }X,Y,Ans; inline bool operator<(const BigNum &p,const BigNum &q) {if(p.a[0]!=q.a[0]) return p.a[0]<q.a[0];int i;for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i]){return p.a[i]<q.a[i];}return false; } inline bool operator==(const BigNum &p,const BigNum &q) {if(p.a[0]!=q.a[0]) return false;int i;for(i=p.a[0];i>=1;i--) if(p.a[i]!=q.a[i]){return false;}return true; } inline BigNum operator-(const BigNum &p,const BigNum &q) {int i;BigNum ans=p;for(i=1;i<=q.a[0];i++){ans.a[i]-=q.a[i];if(ans.a[i]<0){ans.a[i]+=Base;ans.a[i+1]--;}}while((!ans.a[ans.a[0]])&&ans.a[0]) ans.a[0]--;return ans; } inline BigNum operator*(const BigNum &p,const BigNum &q) {int i,j;BigNum ans; ans.a[0]=max(p.a[0],q.a[0]);for(i=1;i<=p.a[0];i++){for(j=1;j<=q.a[0];j++){ans.a[i+j-1]+=p.a[i]*q.a[j];ans.a[i+j]+=ans.a[i+j-1]/Base;ans.a[i+j-1]%=Base;}}while(ans.a[ans.a[0]+1]) ans.a[0]++;while(!ans.a[ans.a[0]]) ans.a[0]--;return ans; } inline bool Judge_Ou(BigNum p) {if(!p.a[0]) return 1;return (p.a[1]&1)?0:1; } inline BigNum Div2(BigNum p) {BigNum ans;ans.a[0]=p.a[0];int i;for(i=p.a[0];i>=1;i--){ans.a[i]+=(p.a[i]>>1);if(p.a[i]&1) p.a[i-1]+=Base;}while(!ans.a[ans.a[0]]) ans.a[0]--;return ans; } inline BigNum Mul2(BigNum p) {BigNum ans;ans.a[0]=p.a[0];int i;for(i=1;i<=p.a[0];i++){p.a[i]<<=1;if(p.a[i]>Base){ans.a[i+1]+=p.a[i]/Base;p.a[i]%=Base;}ans.a[i]+=p.a[i];}while(ans.a[ans.a[0]+1]) ans.a[0]++;return ans; } int main() {freopen("data.in","r",stdin);freopen("my.out","w",stdout);Read_S(SX);reverse(SX+1,SX+strlen(SX+1)+1);X=BigNum(SX);Read_S(SY);reverse(SY+1,SY+strlen(SY+1)+1);Y=BigNum(SY);Ans.a[0]=Ans.a[1]=1;while(!(X==Y)){ // P(X); Pl(Y);bool BoX=Judge_Ou(X),BoY=Judge_Ou(Y);if(BoX){if(BoY){X=Div2(X); Y=Div2(Y); Ans=Mul2(Ans);}else{X=Div2(X);}}else{if(BoY){Y=Div2(Y);}else{BigNum p,q; if(X<Y) p=Y,q=X;else p=X,q=Y;X=p-q; Y=q;}}}Ans=Ans*X;Pl(Ans);return 0; } 帶優化的正確姿勢

?

轉載于:https://www.cnblogs.com/gaojunonly1/p/10433546.html

總結

以上是生活随笔為你收集整理的一本通1627【例 3】最大公约数的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。