联系: http://soj.me/1732

Constraints



Time Limit: 1 secs, Memory Limit: 32 MB



Description:



Alice is a beautiful and clever girl. Bob would like to play with Alice.


One day, Alice got a very big rectangle and wanted to divide it into small square pieces. Now comes a problem: if all pieces of small squares are of the same size, how big could the squares be? To Alice, it’s easy to solve the problem.
However, she was very busy, so she asked Bob to help her. You know Alice is such a lovely girl and of course Bob won’t refuse her request. But Bob is not so smart and he is especially weak in math. So he turns to you—a genius at programming.


Alice will inform Bob the length and width of the big rectangle, and Bob have to tell her the longest length for the small square. All of these numbers are in their binary representations.




Input:



The first line of the input is a positive integer. This is the number of the test cases followed. Each test case contains two integer L and W in their binary representation which tells you the length and width of the very big rectangle
(0<L, W<2^1000). There may be one or several spaces between these integers.



Output:



The output of the program should consist of one line of output for each test case. The output of each test case only contains the longest length for the small squares in its binary representation. No any redundant spaces are needed.



Sample Input:



2

100 1000

100 110

Sample Output:



100

10

分析:本题的大意就是给出两个数的二进制。求出他们的最大公约数,要用辗转相除法,因为本题的数据范围较大,须要使用高精度,假设简单套用使用辗转相除法gcd(n, m) = gcd(m, n%m)来求的话,那么就要完毕一个高精度的除法的程序;

由于本题的输入和输出都使用二进制表示。所以能够使用下面方法来求最大公约数,(仅仅须要用高精度的除法和以为运算);

本题採用的算法例如以下:

if a = 2p, b = 2q, then gcd(a, b) = 2*gcd(p, q);

if a = 2p, b = 2q+1, then gcd(a, b) = gcd(p, b);

if a = 2p+1, b = 2q, then gcd(a, b) = gcd(a, q);

if a = 2p+1, b = 2q+1, then gcd(a, b) = gcd(a-b, b) (assume a > b)

容易看出前三种情况都会导致当中一个整数减半,这样递减的速度是非常快的,并且因为输入的是以二进制的方式输入,推断a, b的方式非常easy;

那会不会连续调用第四种情况呢?答案是不会的。原因是:

当a = 2p+1, b = 2q+1时:

gcd(a, b) = gcd(a-b, b) = gcd(2(p-q), 2q+1) = gcd(p-q, 2q+1);

明显不可能出现连续调用第四种情况,时间复杂度也和标准的转转相除法一样是O(logn);

代码例如以下:

// Problem#: 1732
// Submission#: 2822044
// The source code is licensed under Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License
// All Copyright reserved by Informatic Lab of Sun Yat-sen University
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define MAXN 10005
#define RST(N)memset(N, 0, sizeof(N))
using namespace std; typedef struct Node_
{
int len;
int v[MAXN];
}Node; Node n, m;
int cas;
char str1[MAXN], str2[MAXN]; Node Tr(char *str) //把字符串转换成数字形式;
{
Node N;
int len = strlen(str);
N.len = len;
for(int i=0; i<len; i++) N.v[i] = str[len-1-i]-'0';
return N;
} bool CMP(Node n, Node m) //比較两个数的大小;
{
if(n.len < m.len) return true;
if(n.len > m.len) return false;
for(int i=n.len-1; i>=0; i--) {
if(n.v[i] < m.v[i]) return true;
else if(n.v[i] > m.v[i]) return false;
}
return false;
} Node Minus(Node n, Node m) //大整数高精度相减。注意是二进制相减;
{
Node N = n;
int borrow = 0, temp, i; //borrow为借位;
for(i=0; i<m.len; i++) { //从低位减起;
temp = N.v[i] - borrow - m.v[i];
if(temp >= 0) { //没有借位。
borrow = 0, N.v[i] = temp;
}else {
borrow = 1, N.v[i] = temp + 2;
}
}
for(; i<n.len; i++) { //处理剩余位数;(如果n > m)
temp = N.v[i] - borrow;
if(temp >= 0) {
borrow = 0, N.v[i] = temp;
}else {
borrow = 1, N.v[i] = temp + 2;
}
}
while(N.len >= 1 && !N.v[N.len-1]) N.len--;
return N;
} Node div(Node n) //大整数除2;因为是二进制,其本质就是移位;
{
Node ret;
ret.len = n.len-1;
for(int i=0; i<ret.len; i++) ret.v[i] = n.v[i+1];
return ret;
} void gcd(Node n, Node m) //求大整数的公约数;
{
long cnt = 0;
while(n.len && m.len) {
if(n.v[0]) {
if(m.v[0]) { //a = 2p+1, b = 2q+1 情况
if(CMP(n, m)) m = Minus(m, n);
else n = Minus(n, m);
}else m = div(m); //a = 2p+1, b = 2q情况;
}else {
if(m.v[0]) n = div(n); //a = 2p, b = 2q+1情况。
else {
n = div(n), m = div(m); //a = 2p, b = 2q情况。
cnt++;
}
}
}
if(m.len) for(int i=m.len-1; i>=0; i--) printf("%d", m.v[i]); //输出结果;
else for(int i=n.len-1; i>=0; i--) printf("%d", n.v[i]);
while(cnt--) printf("0");
printf("\n");
} int main()
{
scanf("%d", &cas);
while(cas--) {
scanf("%s %s", str1, str2);
n = Tr(str1), m = Tr(str2);
gcd(n, m);
}
return 0;
}

版权声明:本文博主原创文章,博客,未经同意不得转载。

Sicily 1732 Alice and Bob (二进制最大公约数)的更多相关文章

  1. CodeForces 346A Alice and Bob (数学最大公约数)

    题意:有一堆数,然后有两个人轮流从中取出两个数,这两个数的差的绝对值不在这个集合,然后把这个数放进这个集合,如果哪个人不能拿了,就是输了,问你谁赢. 析:当时连题意都没看好,以为拿出两个数,就不放回了 ...

  2. SDUT 2608 Alice and Bob (巧妙的二进制)

    Alice and Bob Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里^_^ 题目描述 Alice and Bob like playing ...

  3. Alice and Bob(2013年山东省第四届ACM大学生程序设计竞赛)

    Alice and Bob Time Limit: 1000ms   Memory limit: 65536K 题目描述 Alice and Bob like playing games very m ...

  4. sdutoj 2608 Alice and Bob

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2608 Alice and Bob Time L ...

  5. 位运算 2013年山东省赛 F Alice and Bob

    题目传送门 /* 题意: 求(a0*x^(2^0)+1) * (a1 * x^(2^1)+1)*.......*(an-1 * x^(2^(n-1))+1) 式子中,x的p次方的系数 二进制位运算:p ...

  6. 2013年山东省第四届ACM大学生程序设计竞赛 Alice and Bob

      Alice and Bob Time Limit: 1000ms   Memory limit: 65536K 题目描述 Alice and Bob like playing games very ...

  7. ny788 又见Alice and Bob

    又见Alice and Bob 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 集训生活如此乏味,于是Alice和Bob发明了一个新游戏.规则如下:首先,他们得到一个 ...

  8. 2013年山东省第四届ACM大学生程序设计竞赛E题:Alice and Bob

    题目描述 Alice and Bob like playing games very much.Today, they introduce a new game. There is a polynom ...

  9. 2016中国大学生程序设计竞赛 - 网络选拔赛 J. Alice and Bob

    Alice and Bob Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) ...

随机推荐

  1. 【Java GUI】Java面板基础:JPanel

    有两个面板,常见的面板(JPanel)和滚动面板(JScrollPane) Jpanel 面板是一种常见的容器,JPanel的作用是实现接口层次结构,面放入一些组件.也能够在上面绘画,将放有组件和有画 ...

  2. 【iOS】Web Color 的 Swift 实现

    用Swift语言重写Web Color这个类. 这次是用函数实现的,感觉也非常简洁.眼下(2014.6.28) Xcode 6的方法提示还不健全,就仅仅实现了用颜色名字创建颜色的功能. 最新代码&am ...

  3. Objective-C路成魔【11-多态性、动态类型和动态绑定】

    郝萌主倾心贡献.尊重作者的劳动成果,请勿转载. 假设文章对您有所帮助,欢迎给作者捐赠.支持郝萌主.捐赠数额任意,重在心意^_^ 我要捐赠: 点击捐赠 Cocos2d-X源代码下载:点我传送 多态这个其 ...

  4. 设计模式--简单工厂VS工厂VS抽象工厂

    前几天我一直在准备大学毕业生,始终绑起来,如今,终于有时间去学习设计模式.我们研究今天的话题是植物三口之家的设计模式的控制--简单工厂VS工厂VS抽象工厂. 经过细心推敲,我们不难得出:工厂模式是简单 ...

  5. Android APK反编译详解(非常有用)

    如何学习最快呢?无疑是通过研究别人的源代码? 但是,获取别人的源代码,比较困难.本文,仅限于用于学习开发. 这段时间在学Android应用开发,在想既然是用Java开发的应该很好反编译从而得到源代码吧 ...

  6. java_访问权限修饰符

    java的访问权限修饰符有四种,根据权限由大到小的顺序为:public,protected,包访问权限(默认,没有修饰符),private. 根据修饰的东西不同,详细介绍如下: 1.修饰类的话分为两种 ...

  7. 终结者:具体解释Nginx(一)

            相信非常多人都听过Nginx.这个小巧的东西能够和Apache及IIS相媲美. 那么它有什么作用呢?一句话.它是一个减轻Web应用server(如Tomcat)压力和实现Web应用se ...

  8. 用CSS3制作很特别的波浪形菜单

    原文:用CSS3制作很特别的波浪形菜单 网页菜单我们见过很多,各种炫酷的.实用的菜单比比皆是.昨天我看到一款很特别的CSS3菜单,它的外形是波浪形的,弯弯曲曲,结合背景,看上去还挺不错的,下面看下一效 ...

  9. [Tool]利用Advanced Installer建立x86/x64在一起的安装程式

    原文 [Tool]利用Advanced Installer建立x86/x64在一起的安装程式 之前使用InstallShield做安装程式时,如果要将程式放在Program Files的话,需要分别针 ...

  10. Codeforces 383C . Propagating tree【树阵,dfs】

    标题效果: 有一棵树,有两种操作模式对本树:1:表示为(1 x val),在NOx加在节点上val,然后x每个节点加上儿子- val.给每个儿子一个儿子在一起-(- val),加到没有儿子为止.2:表 ...