SGU 126 Boxes(模拟题|二进制)
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(模拟题|二进制)的更多相关文章
- SGU 126. Boxes --- 模拟
<传送门> 126. Boxes time limit per test: 0.25 sec. memory limit per test: 4096 KB There are two b ...
- 找规律 SGU 126 Boxes
题目地址:http://acm.sgu.ru/problem.php?contest=0&problem=126 /* 找规律,智商不够,看了题解 详细解释:http://blog.csdn. ...
- sgu 126 Boxes
题意:较大的容量减较小的容量,较小的容量翻倍.问操作几回其中一个空. 开始用set判重,重复就不可行.不过状态最多有2e18种.不仅爆内存,还超时.然后找规律.发现只有比例为1:1,1:3,1:7,3 ...
- 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 ...
- PAT甲级 模拟题_C++题解
模拟题 PAT (Advanced Level) Practice 模拟题 目录 1008 Elevator (20) 1042 Shuffling Machine (20) 1046 Shortes ...
- poj 1008:Maya Calendar(模拟题,玛雅日历转换)
Maya Calendar Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 64795 Accepted: 19978 D ...
- poj 1888 Crossword Answers 模拟题
Crossword Answers Time Limit: 1000MS Memory Limit: 30000K Total Submissions: 869 Accepted: 405 D ...
- CodeForces - 427B (模拟题)
Prison Transfer Time Limit: 1000MS Memory Limit: 262144KB 64bit IO Format: %I64d & %I64u Sub ...
- sdut 2162:The Android University ACM Team Selection Contest(第二届山东省省赛原题,模拟题)
The Android University ACM Team Selection Contest Time Limit: 1000ms Memory limit: 65536K 有疑问?点这里 ...
随机推荐
- Linux --- Ubuntu16.04.5 LTS 虚拟机安装后的软件安装基础操作总结
1. 配置安装源 因为默认是使用Ubuntu官方服务器,国内电脑使用外国服务器较慢,所以需使用国内的服务器(以下清华大学服务器为例). 方法一: (此过程很慢,实在不动就取消吧,加载一部分也够用,以后 ...
- PE 学习之路 —— 区块表
1. 前述 在 NT 头结束后,紧接着就是区块表,区块表包含每个块在映象中的信息,分别指向不同的区块实体. 2. 区块表 区块表是一个 IMAGE_SECTION_HEADER 结构数组,这个结构包含 ...
- 使用cmd时cd命令失效
使用cmd时cd命令失效 近日使用cmd时总是出现无法cd到指定目录的情况 如下图所示 输入cd命令后依旧停留在原始路径 解决方法: 输入 cd D:\CE-5\Training_Sanple\n ...
- aircrack-ng 破解无线网络
1.科普当今时代,wifi 已成为我们不可缺少的一部分,上网.看视频.玩游戏,没有 wifi 你就等着交高额的流量费吧,本来我想单独的写 wpa 破解和 wps 破解,后来觉得分开写过于繁琐,索性合并 ...
- BZOJ 小Z的袜子 2038 国家集训队
过程: 想了很久如何求组合数C(n,m),然而 YL 同学提醒了可以直接除以 2*n*(n - 1 ).改了之后果然对了,以为一定是一次性AC 了,然而 WA 了3次,尴尬 —— 神 TM,ZC 苟看 ...
- 20155203 2016-2017-2《Java程序设计》课程总结
目录 一.每周作业链接汇总 自认为写得最好一篇博客是?为什么? 作业中阅读量最高的一篇博客是?谈谈经验 作业中与师生交互最多的一篇博客是?谈谈收获 二.实验报告链接汇总 三.代码托管链接 四.课堂项目 ...
- 20155239 2016-2017-2 《Java程序设计》第9周学习总
教材学习内容 JDBC 简单功能 连接数据源,如数据库 传给数据库查询和更新指令 获取并处理数据库返回结果(对查询等的响应) public void connectDBAndQuery(String ...
- 20155320信息安全系统设计第二周课堂考试总结及myod的实现
20155320 信息安全系统设计第二周课堂考试总结及myod的实现 第二周测试一二已在课上提交 第二周测试3-gdb测试 用gcc -g编译vi输入的代码 在main函数中设置一个行断点 在main ...
- [Vani有约会]雨天的尾巴 线段树合并
[Vani有约会]雨天的尾巴 LG传送门 线段树合并入门好题. 先别急着上线段树合并,考虑一下这题的暴力.一看就是树上差分,对于每一个节点统计每种救济粮的数量,再一遍dfs把差分的结果统计成答案.如果 ...
- Drupal views 中合并显示字段
如图, 需要显示如下数据表格 表格的第三列是由两个字段组成的.分别是title 标题字段和body 内容字段. 默认情况下,一列只显示一个字段.如何同时显示两个呢? 这个问题难不到强大的views,要 ...