HDOJ-5050-Divided Land 解题报告
来源:互联网 发布:电气控制系统设计软件 编辑:程序博客网 时间:2024/06/05 09:02
二进制高精度GCD模拟题。题意:你有一块长和宽都是整数的矩形土地,作为市长,你需要把这块土地分割成很多块边长相等的正方形土地,并且分割完后土地不能有剩余,而且正方形的边长要尽量大。现在以二进制数的方式来告诉你这块土地的长和宽,请你也用二进制数的形式来表示正方形的边长。
我的解题思路:首先分析题意必须要知道其实这就是求矩形土地长和宽的最大公约数,这个最大公约数就是正方形的边长。其次,由于长和宽的范围是不大于2^1000,说明这个二进制数的长度可以达到一千,就算转换为十进制数,也没有任何数据类型可以存得下,所以这里要用到高精度。最后,求二进制数的GCD有这样三个性质(假设a和b都是二进制数):
1.如果a和b都是偶数,那么gcd(a, b) = 2 * gcd(a>>1, b>>1);
2.如果a是奇数、b是偶数,那么gcd(a, b) = gcd(a, b>>1);
3.如果a和b都是奇数且a>b,那么gcd(a, b) = gcd(a-b, b);
不要问我如果a和b都是奇数且a和b相等怎么办了,相等的话他们本身就是最大公约数了。有了以上的公式,模拟就可以写了。
我的解题代码:
#include <cstdio>#include <cstdlib>#include <cstring>#include <cctype>#include <cmath>#include <algorithm>#include <vector>#include <queue>#include <stack>#include <list>#include <map>using namespace std;#define N 1005char l[N], w[N]; //两个二进制数int ln, wn; //两个二进制数的长度int o = 0; //输出答案时需要添加的后缀0的数量int t; //样例数void DataProcess(); //计算并输出二进制最大公约数void L(); //计算l -= w;void W(); //计算w -= l;int main(){ int tn = 1; scanf("%d", &t); while (t--) { scanf("%s %s", l, w); o = 0; ln = strlen(l); wn = strlen(w); printf("Case #%d: ", tn++); if ((ln == 1 && l[0] == '1') || (wn == 1 && w[0] == '1')) //特例直接输出 { puts("1"); continue; } DataProcess(); } return 0;}void DataProcess(){ while (ln != wn || strncmp(l, w, ln) != 0) //当两数不相等时,求其最大公约数 { if (l[ln-1] == w[wn-1] && l[ln-1] == '0' && ln > 0 && wn > 0) //都是偶数 { o++; //gcd(l,w) = 2 * gcd(l,w),所以最终输出边长时要添加0 ln--; //相当于右移一位 wn--; } else if (l[ln-1] != w[wn-1] && ln > 0 && wn > 0) //一奇一偶 { if (l[ln-1] == '0') ln--; else wn--; } else if (l[ln-1] == w[wn-1] && l[ln-1] == '1' && ln > 0 && wn > 0) //都是奇数 { if (ln == wn) { if (strncmp(l, w, ln) > 0) L(); //l > w else W(); //w > l } else if (ln > wn) L(); else W(); } } for (int i=0; i<ln; ++i) putchar(l[i]); for (int i=0; i<o; ++i) putchar('0'); putchar('\n'); return;}void L(){ int i = ln - 1; int j = wn - 1; int k; while (j != -1) { l[i] -= w[j] - '0'; if (l[i] < '0') { l[i-1] -= 1; //借位 l[i] += 2; } i--; j--; } for (; i>=0; --i) { if (l[i] < '0') //借位 { l[i] += 2; l[i-1] -= 1; } } for (k=0; k<ln; ++k) { if (l[k] == '0') continue; break; } for (i=0; i<ln-k; ++i) //相减后的数因为可能有前缀0,所以要向前移 { l[i] = l[k+i]; } ln -= k; //相减后的长度 return;}void W() //与L()基本相同{ int j = ln - 1; int i = wn - 1; int k; while (j != -1) { w[i] -= l[j] - '0'; if (w[i] < '0') { w[i] += 2; w[i-1] -= 1; } i--; j--; } for (; i>=0; --i) { if (w[i] < '0') { w[i] += 2; w[i-1] -= 1; } } for (k=0; k<wn; ++k) { if (w[k] == '0') continue; break; } for (i=0; i<wn-k; ++i) { w[i] = w[k+i]; } wn -= k; return;}
0 0
- HDOJ-5050-Divided Land 解题报告
- hdu 5050 Divided Land
- HDU - 5050 Divided Land
- hdu 5050 Divided Land
- hdu 5050 Divided Land
- HDU 5050 Divided Land
- hdu 5050 Divided Land java
- Divided Land
- HDU-#5050 Divided Land(高精度)
- Hdu-5050 Divided Land(Java高精度)
- HDU 5050 Divided Land JAVA GCD
- HDU 5050 Divided Land(最大公约数Java)
- HDU——5050 Divided Land
- HDU 5050 Divided Land(进制转换)
- hdu 5050 Divided Land(高精度)
- hdu 5050——Divided Land
- hdu 5050 Divided Land (java大数)
- hdu 5050 Divided Land(高精度gcd)
- objective c设计模式--KVC
- POJ 1182 食物链(种类并查集)
- 【实验报告】《数据结构》实验一: VC编程工具的灵活使用
- POJ 2482——Stars in Your Window(线段树+扫描线,二维区域最值转化为线段树-经典)最浪漫的题目
- Linked List Cycle
- HDOJ-5050-Divided Land 解题报告
- 【DFS】HDU 1364 && POJ 1071 Illusive Chase
- LCA - RMQ & TRAJAN ZOJ 3195
- 关闭防火墙
- 黑马程序员——C语言结构体
- BZOJ 1977 次小生成树 倍增LCA
- 【Struts2学习笔记(10)】自定义拦截器管理权限访问
- NSBundle介绍
- [CALayer release]: message sent to deallocated instance iOS内存过度释放问题