Translate:Sgu/126

126. 盒子

time limit per test: 0.5 sec.

memory limit per test: 4096 KB

有两个盒子. 第一个盒子里有A 个球, 第二个里面有B 个球 (0 < A + B < 2147483648). 允许把球在两个盒子间移动. 从一个盒子向另一个盒子移动球的数目必须等

于接受盒子现有的球的数量. 你需要搞清楚, 最后球能不能都移动到一个盒子里

Input

第一行两个整数 A 和 B, 空格分隔.

Output

一行数字 N – 需要移动的次数,如果不存在,输出-1

Sample Input

2 6

Sample Output

2

数学解法

一个二进制的数学题

原题:狠狠地打我!

想法:这题是一道数学题,裸的。

原理是二进制,这道题的解法是:先将两数变得互质,即都除去最大公约数,再判断,若相加为2的k次幂则有解,否则无解。

证:首先,我们是要使两数相等,则其步骤数显然只与相对大小有关,因为,转移的数量时刻只与较小数大小有关,且只有加减法参与,两数的最大公约数不会变小,因而约去和不约效果一致。

其次,证明互质时,有解当且仅当相加为2的k次幂:

充分性:若满足两数和为2的k次幂,则,可以转换角度看待一个

操作:

操作的过程是,在二进制下,将较小的数,向左移

一位,而较大的数随之变化。这样,我们将看到,

较小数,无论是谁,右边的连续零位将不断增加,

且较大的数也必然如此,因为两者低位每位相加必

须为零。这样每个操作就是不断将右边的连续零位

不断加长,到后面时,必然会出现,零位为k-1个,

第k位为1。

必要性:若不满足,则,和中至少有一位为1,那么,不妨考虑最右

边的那个,那么,若其是0+1得来,则,较小数无论是谁,

左移都不可以使得两数相等,因为,相等就必须是该位的右

一位两数同时为一,而左移会使那一位变为0,矛盾。若为

两个低位的1相加而来,则操作后,较小数那位的1消失,又

变为0+1形式,所以,这时,两数永远不可能相等,就不会

达到一个为0。

那么,怎样快速的计算步骤数呢?

由于有解的且互质的两个数二进制下,最右边的“1”的位置相同,所以一次操作只能移动一个位置,而我们要将那个“1”移到k+1位,所以,最后的结果是

log2(a+b)-log2(a and -a)

注意,好像SGU用这个式子会RE on 3……

#include <stdio.h>
using namespace std; int gcd(int a, int b)
{
return b?gcd(b,a%b):a;
}
int main()
{
int a, b;
scanf("%d%d", &a, &b);
int s = (a+b)/gcd(a, b), res = 0;
while (!(s & 1))
{
s /= 2;
res++;
}
if (s == 1) printf("%d", res);
else printf("-1");
return 0;
}

模拟解法

首先我们需要知道,求 A,B 的步数其实就等同于求 A/gcd(A,B),B/gcd(A,B) 的步数。

对于这个的证明很明显,每次移动的求一定是 gcd(A,B) 的倍数。

对于每次移动,令 A = A/gcd(A,B) ,B = B/gcd(A,B),讨论情况 :

(1) A,B都为偶数(不可能)

(2) A,B有一个为奇数 (无解,很明显吧,因为A+B都是奇数了)

(3) A,B都是奇数-> 假设A是较小的那一个,那么就可以变化为 A*2,B-A ,然后我们的新目标就变成了求解 A*2,B-A 的步数

结束条件 A=0 或 B=0

容易证明,上述步骤重复次数最多不超过 log(A+B)次

#include<iostream>
using namespace std;
int gcd(int a,int b)
{
if(b!=0) return gcd(b,a%b);
return a;
}
int A0,B0;
int solve(int A,int B)
{
if(!A||!B) return 0;
int t=gcd(A,B);
A/=t;B/=t;
if(!(A%2==1&&B%2==1)) return -1;
if(A>B) swap(A,B);
t=solve(A*2,B-A);
return t==-1?-1:t+1;
}
int main()
{
cin>>A0>>B0;
cout<<solve(A0,B0);
return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

SGU 126 Boxes(模拟题|二进制)的更多相关文章

  1. SGU 126. Boxes --- 模拟

    <传送门> 126. Boxes time limit per test: 0.25 sec. memory limit per test: 4096 KB There are two b ...

  2. 找规律 SGU 126 Boxes

    题目地址:http://acm.sgu.ru/problem.php?contest=0&problem=126 /* 找规律,智商不够,看了题解 详细解释:http://blog.csdn. ...

  3. sgu 126 Boxes

    题意:较大的容量减较小的容量,较小的容量翻倍.问操作几回其中一个空. 开始用set判重,重复就不可行.不过状态最多有2e18种.不仅爆内存,还超时.然后找规律.发现只有比例为1:1,1:3,1:7,3 ...

  4. Western Subregional of NEERC, Minsk, Wednesday, November 4, 2015 Problem K. UTF-8 Decoder 模拟题

    Problem K. UTF-8 Decoder 题目连接: http://opentrains.snarknews.info/~ejudge/team.cgi?SID=c75360ed7f2c702 ...

  5. PAT甲级 模拟题_C++题解

    模拟题 PAT (Advanced Level) Practice 模拟题 目录 1008 Elevator (20) 1042 Shuffling Machine (20) 1046 Shortes ...

  6. poj 1008:Maya Calendar(模拟题,玛雅日历转换)

    Maya Calendar Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 64795   Accepted: 19978 D ...

  7. poj 1888 Crossword Answers 模拟题

    Crossword Answers Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 869   Accepted: 405 D ...

  8. CodeForces - 427B (模拟题)

    Prison Transfer Time Limit: 1000MS   Memory Limit: 262144KB   64bit IO Format: %I64d & %I64u Sub ...

  9. sdut 2162:The Android University ACM Team Selection Contest(第二届山东省省赛原题,模拟题)

    The Android University ACM Team Selection Contest Time Limit: 1000ms   Memory limit: 65536K  有疑问?点这里 ...

随机推荐

  1. spark or sparkstreaming的内存泄露问题?

    关于sparkstreaming的无法正常产生数据---->到崩溃---->到数据读写极为缓慢(或块丢失?)问题 前两阶段请看我的博客:https://www.cnblogs.com/wa ...

  2. Go 学习之路:Println 与 Printf 的区别

    Println 和Printf 都是fmt包中公共方法:在需要打印信息时常用的函数,那么二函数有什么区别呢? 附上代码 package main import ("time"&qu ...

  3. DotNetty学习笔记

    DotNetty项目本身的示例很容易运行起来,但是具体到真实的应用场景,还是需要进一步理解DotNetty的通道处理细节,这样才能够在实际项目应用中处理具体的问题. 简单的场景下会有以下几个问题,第一 ...

  4. dotnet Core 2.0学习笔记(一)

    一:Dotnet Core Windows运行环境,标红部分要注意 https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites ...

  5. 学号20155311 2016-2017-2 《Java程序设计》第一次实验报告

    课程:Java程序设计 实验名称:Java开发环境的熟悉 实验目的与要求: 没有Linux基础的同学建议先学习<Linux基础入门(新版)><Vim编辑器> 课程: 完成实验. ...

  6. 20155327 2016-2017-2《Java程序设计》课程总结

    20155327 2016-2017-2<Java程序设计>课程总结 每周作业链接汇总 预备作业1:http://www.cnblogs.com/l97----/p/6160983.htm ...

  7. 用 GSL 求解超定方程组及矩阵的奇异值分解(SVD)

    用 GSL 求解超定方程组及矩阵的奇异值分解(SVD) 最近在学习高动态图像(HDR)合成的算法,其中需要求解一个超定方程组,因此花了点时间研究了一下如何用 GSL 来解决这个问题. GSL 里是有最 ...

  8. MySQL入门篇(一)之MySQL部署

    MySQL 二进制免编译安装 (1)下载二进制免编译版本mysql 5.6.35 [root@localhost tools]# wget http://mirrors.sohu.com/mysql/ ...

  9. 【MongoDB安装】MongoDB在centos linux平台安装

    参考:http://www.runoob.com/mongodb/mongodb-linux-install.html 一..下载安装包 下载方式: 1.登录官网download,然后通过xftp传到 ...

  10. python5

    print应用 // 输出两行 print "hahaha" print "hehehe" // 输出在同一行里 print "hahaha" ...