题目

Sheng bill有着惊人的心算能力,甚至能用大脑计算出两个巨大的数的GCD(最大公约 数)!因此他经常和别人比

赛计算GCD。有一天Sheng bill很嚣张地找到了你,并要求和你比 赛,但是输给Sheng bill岂不是很丢脸!所以你

决定写一个程序来教训他。

输入格式

共两行: 第一行:一个数A。 第二行:一个数B。

0 < A , B ≤ 10 ^ 10000。

输出格式

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

输入样例

12

54

输出样例

6

题解

时隔大半年,我回来A这道题啦【当初写的太BUG了】

求GCD,很容一想到辗转相除,而高精不好操作取模,这就用到了辗转相除法的本质:更相减损法

GCD(a,b) = GCD(a,a-b) 【a >b】

然而这样会T,所以我们还要优化:

GCD(a,b) = 2*GCD(a/2,b/2) 【2|a且2|b】

GCD(a,b) = GCD(a/2,b) 【2|a】

GCD(a,b) = GCD(a,b/2) 【2|b】

GCD(a,b) = GCD(a,a-b) 【a >b】

加上个压位高精【高精减法,高精除低精,高精乘低精,高精比较】

就可以A了

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#define LL long long int
#define REP(i,n) for (int i = 1; i <= (n); i++)
using namespace std;
const int maxn = 10005,B = 4,Base = 10000,maxm = 100005,INF = 1000000000;
struct NUM{
int s[maxn],len;
NUM() {memset(s,0,sizeof(s)); len = 0;}
};
istream& operator >>(istream& in,NUM& a){
string s;
in>>s;
int temp = 0,t = 1;
for (int i = s.length() - 1; i >= 0; i--){
temp = temp + t * (s[i] - '0');
if (t * 10 == Base) a.s[++a.len] = temp,temp = 0,t = 1;
else t *= 10;
}
if (temp) a.s[++a.len] = temp;
return in;
}
ostream& operator <<(ostream& out,const NUM& a){
if (!a.len) out<<0;
else {
printf("%d",a.s[a.len]);
for (int i = a.len - 1; i > 0; i--) printf("%04d",a.s[i]);
}
return out;
}
bool check(const NUM& a){return !(a.s[1] & 1);}
bool equal(const NUM& a,const NUM& b){
if (a.len != b.len) return false;
REP(i,a.len) if (a.s[i] != b.s[i]) return false;
return true;
}
bool operator <(const NUM& a,const NUM& b){
if (a.len < b.len) return true;
if (a.len > b.len) return false;
for (int i = a.len; i > 0; i--){
if (a.s[i] < b.s[i]) return true;
if (a.s[i] > b.s[i]) return false;
}
return false;
}
void Half(NUM& a){
int carry = 0,temp;
for (int i = a.len; i > 0; i--){
temp = (a.s[i] + carry * Base) / 2;
carry = a.s[i] + carry * Base - temp * 2;
a.s[i] = temp;
}
while (!a.s[a.len]) a.len--;
}
void Twice(NUM& a){
int carry = 0,temp;
for (int i = 1; i <= a.len; i++){
temp = a.s[i] * 2 + carry;
a.s[i] = temp % Base;
carry = temp / Base;
}
while (carry) a.s[++a.len] = carry % Base,carry /= Base;
}
NUM operator -(const NUM& a,const NUM& b){
NUM c; c.len = a.len;
int carry = 0,temp;
for (int i = 1; i <= a.len; i++){
temp = a.s[i] - b.s[i] + carry;
if (temp < 0) carry = -1,temp += Base;
else carry = 0;
c.s[i] = temp;
}
while (!c.s[c.len]) c.len--;
return c;
}
int main(){
NUM A,B; int cnt = 0;
cin>>A>>B;
while (!equal(A,B)){
if (check(A) && check(B)) Half(A),Half(B),cnt++;
else if (check(A)) Half(A);
else if (check(B)) Half(B);
else {
if (B < A) swap(A,B);
B = B - A;
}
}
while (cnt--) Twice(A);
cout<<A<<endl;
return 0;
}

最新文章

  1. try...except 错误记录添加logging
  2. CODEVS 3145 汉诺塔游戏 递归
  3. 启动PL/SQL Developer 报字符编码不一致错误 Database character set (AL32UTF8) and Client character set (ZHS16GBK) are different. Character set conversion may cause unexpected results. Note: you can set the client
  4. Android应用不随手机屏幕旋转的方法
  5. Android解析qq聊天记录表情
  6. MVC3.0 提交表单的方法
  7. 【规律】【贪心】【数学】HDU 5573 Binary Tree
  8. 开发自定义View
  9. DataTable循环删除行
  10. UNIX网络编程5 POSIX 消息队列
  11. CentOS6使用第三方yum源安装更多rpm软件包
  12. Linux注销在线用户
  13. mysql alter使用
  14. Hibernate注解开发详解
  15. 面试官,你再问我 Bit Operation 试试?
  16. JDBC 利用反射 配置文件
  17. 腾讯2019年暑期实习生招聘在线笔试技术研究和数据分析方向第二题(python)
  18. linux和windows共享目录
  19. vue-14-less 语法的使用
  20. java 工具

热门文章

  1. JDK5后的特性整理
  2. [转]不让iTunes备份到c盘
  3. dedecms织梦首页被篡改 网站被黑被跳转的解决办法建议
  4. Qt——信号与槽
  5. Java线程和多线程(十)——TimerTask
  6. 10-mongodb启动错误
  7. 导入execl到数据库mysql
  8. 思杰VDI提示“The VDI is not available”
  9. TFTP &amp; commons-net-3.3.jar
  10. Qt BarChart实践