A+B Problem 详细解答 (转载)
此为详细装13版
转载自:https://vijos.org/discuss/56ff2e7617f3ca063af6a0a3
全文如下,未作修改,仅供围观,不代表个人观点:
而且你们假惺惺的用网络流,过程中还是要用加法,我一个加法都没用。
#include <cstdio>
int m, n, a[32768][32768]; int main() { scanf("%d%d", &m, &n); for (int i = 1; i <= m; ++i) { a[i][0] = i; for (int j = 1; j <= n; ++j) { a[0][j] = j; a[i][j] = ++a[i - 1][j]; --a[i - 1][j]; } } printf("%d\n", a[m][n]); }
根据加法的性质,0 为加法单元,满足 m + 0 = m, 0 + n = n
然后就是裸推了:i + j = i + (j - 1) + 1
但是这样会超时,而且在 Vijos 上测数组太大了,编译就错误了。所以要进行优化,合并一个状态:
设 F(i) = i + n, 则 F(0) = n, F(i) = F(i - 1) + 1
#include <cstdio>
int m, n, a[32768];
int main() { scanf("%d%d", &m, &n); a[0] = n; for (int i = 1; i <= m; ++i) { a[i] = ++a[i - 1]; --a[i - 1]; } printf("%d\n", a[m]); }
此时已经可以通过了,然而,本着精益求精的态度,进一步可以用滚动数组优化,变成这样:
#include <cstdio>
int m, n, ans;
int main()
{scanf("%d%d", &m, &n); ans = n; while (m--) ++ans; printf("%d\n", ans); }
这是递推做法的最优解了。然而,事实上,还可以用位运算做,才是真正的最优解。
首先,加法分为两个步骤,一个是数字加,一个是进位。
因为单位二进制中 1 + 1 = 0, 1 + 0 = 1, 0 + 0 = 0, 0 + 1 = 1
正好符合异或的性质。
进位的部分则为 a & b。
但是第一位不可能进位,所以整体移动一位,即 (a & b) << 1.
那么 a + b = (a ^ b) + ((a & b) << 1);
出现了加号!可是这是可以递归的,故程序优化如下:
#include <cstdio>
int m, n;
int add(int a, int b) { if (a == 0) return b; if (b == 0) return a; int s = a ^ b; int t = (a & b) << 1; return add(s, t); } int main() { scanf("%d%d", &m, &n); printf("%d\n", add(m, n)); }
显然,该程序时间复杂度为 Ø(log max{a, b})
因为这是一个尾递归,所以我们可以通过迭代消除它。
#include <cstdio>
int m, n;
int main()
{scanf("%d%d", &m, &n); int u = m & n; int v = m ^ n; while (u) { int s = v; int t = u << 1; u = s & t; v = s ^ t; } printf("%d\n", v); }
即为本题最优解。
在 Vijos 上看不出差距,在洛谷上,位运算解法 2ms 通过,递推的最优解不仅时间很长,还超时了一个点。
不得不说,本题很考察思维,一步一步优化,到达最优。
转载于:https://www.cnblogs.com/radiumlrb/p/5823263.html
A+B Problem 详细解答 (转载)相关推荐
- 校招社招必备核心前端面试问题与详细解答
本文总结了前端老司机经常问题的一些问题并结合个人总结给出了比较详尽的答案.网易阿里腾讯校招社招必备知识点. 原理讲解参考:前端增长-重新定义大前端 在线课程:网易云课堂课程 思否课堂 官方博 ...
- Linux 170个常见问题的详细解答
Linux 170个常见问题的详细解答 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:offi ...
- E - Obstacle Course的详细解答
E - Obstacle Course的详细解答 You are working on the team assisting with programming for the Mars rover. ...
- 详细解答10G SFP+光模块与XFP光模块互连是否能通信
10G SFP+光模块和10G XFP光模块是指每秒可以发送和接收10G数据信号,并能将光转电.电转光的光模块,而SFP与XFP代表的则是其封装形式,10G光模块的封装形式还有XENPAK.X2等,但 ...
- marquee属性详细解答
今天分享下"marquee属性详细解答"这篇文章,文中根据实例编码详细介绍,或许对大家的编程之路有着一定的参考空间与使用价值,需要的朋友接下来跟着云南仟龙Mark一起学习一下吧.该 ...
- PS图层混合模式超详细解答-图层混合模式的原理(Part1)
PS图层混合模式超详细解答-图层混合模式的原理 ☕ 前言 本教程非常详细,请用心看完 本教程如果有如何问题,欢迎评论区留言讨论 本教程为了避免冗余,一些不必要的截图就省略了 本教程只讨论8bit的情形 ...
- pandas.get_dummies函数用法详细解答(实践)
pandas.get_dummies函数用法详细解答(实践) pandas.get_dummies函数用法详细解答(实践)_skywf的博客-CSDN博客 one-hot encoding one-h ...
- 2021年 第13届 全国大学生数学竞赛 初赛(非数学类)试题详细解答
[2020年第12届全国大学生数学竞赛--资源分享 ][1~11届省赛决赛考题及题解(数学类.非数学类).推荐学习网址.复习备考书籍推荐] 2019年 第11届 全国大学生数学竞赛 初赛(非数学类)试 ...
- c语言加法结合性,C语言 运算符 的结合性 怎么理解?求举例子详细解答!!
C语言 运算符 的结合性 怎么理解?求举例子详细解答!! 关注:284 答案:5 信息版本:手机版 解决时间 2019-01-11 21:03 战魂 2019-01-11 10:01 C语言 运算 ...
最新文章
- inner join 和 exists 效率_19条效率至少提高3倍的MySQL技巧
- VTK:可视化算法之PineRootConnectivity
- layui表格弹窗修改_layUI 实现自定义弹窗
- .NET5都来了,你还不知道怎么部署到linux?最全部署方案,总有一款适合你
- Mysql的关联查询语句
- BZOJ1433[ZJOI2009]假期的宿舍——二分图最大匹配
- netsh命令恢复网络_Linux TC模拟网络延迟、丢包、乱序
- Guitar Pro如何更改五线谱的符杆方向
- 易语言斗鱼弹幕助手源码
- 创建你的战略型人际网络
- ubantu桌面,compiz特效和配置
- 银行存储管理系统oracle,课内资源 - 基于JSP和Oracle实现的志愿服务银行系统
- 常用荧光染料的激发和发射波长
- 鼠标滑过,二级菜单显示
- 从容不迫——《稀缺》的读书笔记范文3700字
- 巴西龟饲养日志----半年捉鱼经验总结
- 《枪炮、病菌与钢铁》之一
- 文件名称重命名后,一键恢复的技巧
- G120变频器准备就绪和运行指示信号解析
- 台风中直击流星雨——《一起来看流星雨》速评
热门文章
- URAL 1152. False Mirrors(DP)
- java实现Windows资源管理器
- 构造一个日期类java_Java8 新日期时间类(1)
- hdu5015 矩阵快速幂233(好题)
- hdu2435最大流最小割
- hdu3665 水最短路
- C语言经典例5-输入三个数由小到大输出
- 【Linux 内核 内存管理】内存管理架构 ① ( 内存管理架构组成 | 用户空间 | 内核空间 | MMU 硬件 | Linux 内核架构层次 | Linux 系统调用接口 )
- 【Android 逆向】使用 Python 解析 ELF 文件 ( Capstone 反汇编框架 | PyCharm 中导入 Capstone 反汇编框架 )
- 【Android 高性能音频】Oboe 音频流打开后 耳机 / 音箱 插拔事件处理 ( 设置 Oboe 音频设备 ID | setDeviceId 函数原型 | AudioStream 音频流 )