zoukankan      html  css  js  c++  java
  • [SDOI2009]SuperGCD 高精度GCD

    Description

    Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比
    赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你
    决定写一个程序来教训他。

    Input

    共两行: 第一行:一个数A。 第二行:一个数B。
    0 < A , B ≤ 10 ^ 10000。

    Output

    一行,表示A和B的最大公约数。

    Sample Input

    12
    54

    Sample Output

    6
    solution

    用更相减损术来计算GCD
    优化:
    1.
    对于lena>lenb的情况
    a=a-b*(lena-lenb-1)  (具体实现 只需要标记一下,见代码)
    2.
    把2都提出来  (但是好像并没有快)
    3.
    如果重载运算符,取地址可以变快...

    这题最坑的是 phthon ...
     
     
      1 #include<cstdio>
      2 #include<cstring>
      3 #include<iostream>
      4 #define mem(a,b) memset(a,b,sizeof(a))
      5 #define ll long long
      6 using namespace std;
      7 const int Maxn=10066;
      8 
      9 int comp;
     10 
     11 struct bign
     12 {
     13     int s[Maxn],len;
     14     bign(){len=1;mem(s,0);}
     15     __attribute__((optimize("-O3"))) inline bign operator * (const int &c) const
     16     {
     17         bign now=*this,temp;
     18         temp.len=now.len+15;
     19         int x;
     20         for(int i=1;i<=temp.len;++i)
     21         {
     22             temp.s[i]+=now.s[i]*c;
     23             temp.s[i+1]+=temp.s[i]/10;
     24             temp.s[i]%=10;
     25         }
     26         while(temp.s[temp.len]==0&&temp.len>1)
     27           --temp.len;
     28         return temp;
     29     }
     30     __attribute__((optimize("-O3"))) inline bign operator - (const bign &c) const//取地址会变快... 
     31     {
     32         bign now=*this;
     33         int q1=(now.len>c.len?now.len:c.len);
     34         for(int i=1+comp;i<=q1;++i)
     35         {
     36             now.s[i]-=c.s[i-comp];
     37             if(now.s[i]<0)
     38             {
     39                 --now.s[i+1];
     40                 now.s[i]+=10;
     41             }
     42         }
     43         while(now.len>1&&now.s[now.len]==0)
     44           --now.len;
     45         return now;
     46     }
     47     __attribute__((optimize("-O3"))) inline bign operator / (const int &c) const
     48     {
     49         bign now=*this,temp;
     50         int x=0;
     51         for(int i=now.len;i>=1;--i)
     52         {
     53             temp.s[i]=(x*10+now.s[i])/c;
     54             x=(x*10+now.s[i])%c;
     55         }
     56         temp.len=now.len;
     57         while(temp.len>1&&temp.s[temp.len]==0)
     58           --temp.len;
     59         return temp;
     60     }
     61 };
     62 
     63 bign a,b;
     64 char s[10066];
     65 int ji;
     66 
     67 __attribute__((optimize("-O3"))) inline void read()
     68 {
     69     scanf("%s",s);
     70     int len=strlen(s);
     71     a.len=len;
     72     for(int i=0;i<len;++i)
     73       a.s[len-i]=s[i]-'0';
     74     scanf("%s",s);
     75     len=strlen(s);
     76     b.len=len;
     77     for(int i=0;i<len;++i)
     78       b.s[len-i]=s[i]-'0';
     79 }
     80 
     81 __attribute__((optimize("-O3"))) inline void out11(bign s)
     82 {
     83     for(int i=s.len;i>=1;--i)
     84       printf("%d",s.s[i]);
     85     printf("
    ");
     86 }
     87 
     88 __attribute__((optimize("-O3"))) inline int com()
     89 {
     90     if(a.len>b.len)
     91       return 3;
     92     if(b.len>a.len)
     93       return 1;
     94     int flag;
     95     for(int i=(a.len>b.len?a.len:b.len);i>=1;--i)
     96     {
     97         if(a.s[i]==b.s[i])
     98           continue;
     99         if(a.s[i]>b.s[i])
    100           return 3;
    101         if(a.s[i]<b.s[i])
    102           return 1;
    103     }
    104     return 2;
    105 }
    106 
    107 __attribute__((optimize("-O3"))) inline void Gcd()
    108 {
    109     int flag;
    110     while(1)
    111     {
    112         flag=com();
    113         if(flag==2)
    114           break;
    115         while((a.s[1]&1)==0&&(b.s[1]&1)==0)
    116         {
    117             a=a/2;
    118             b=b/2;
    119             ++ji;
    120         }
    121         if(flag==1)
    122         {
    123             comp=((b.len-a.len-1)>0?(b.len-a.len-1):0);
    124             b=b-a;
    125         }
    126         else
    127         {
    128             comp=((a.len-b.len-1)>0?(a.len-b.len-1):0);
    129             a=a-b;
    130         }
    131     }
    132 }
    133 
    134 __attribute__((optimize("-O3"))) int main(){
    135     
    136     //freopen("1.txt","r",stdin);
    137     
    138     read();
    139     Gcd();
    140     for(int i=1;i<=ji;++i)
    141       a=a*2;
    142     out11(a);
    143 }
    code
     
  • 相关阅读:
    printf和sprintf
    操作数、运算符、表达式
    全自动加法机
    Ascll、GB2312、Ansi
    数组
    循环
    编程命名规范
    浮点数及缺陷
    Android编码规范
    RGB着色对照表
  • 原文地址:https://www.cnblogs.com/A-LEAF/p/7436476.html
Copyright © 2011-2022 走看看