题解:

题目背景

151006 T1

题目描述

Picks 喜欢电路。这天他在研究元电路的时候,需要一个阻值为 (p/q)Ω 的电阻,然而他家中只有一大堆电阻为 1Ω 电阻。由于技术问题,Picks 每次只能把一个电阻串联或并联进整个电路。而 Picks 拿着这么大一堆电阻觉得很浪费,于是他找到你,希望你能告诉他最少用多少个电阻才能拼出他所需要的电阻。

输入格式

输入一行,为两个正整数 P 和 Q 。

输出格式

输出一行一个整数,即最少要用的电阻个数。

样例数据 1

输入  [复制]

3 2

输出

3

备注

【样例说明】
要得到一个 (3/2)Ω 的电阻,可以用两个电阻并联,再串联一个电阻。

【数据范围】
30% 的数据:1≤P,Q≤10;
100% 的数据:1≤P,Q≤1018。

题解:

引用ssoj官网题解:

考虑现在我们的电阻为 a/b Ω,串联一个电阻上去,电阻变为(a+b)/b Ω.
并联一个电阻上去,电阻变为 a/(a+b) Ω 。

假设我们需要的电阻为 P/Q Ω,每次我们都能将 P 减小到比 Q 小,也能将 Q 减小到比 P 小。

那么,我们能进行的操作为:P/Q Ω → (P mod Q)/Q Ω 或 P/Q Ω → P/(Q mod P) Ω

这样的最优性是显然的。

考虑这个操作,会发现和 Euclid(欧几里得) 算法的步骤很接近。由于 Euclid 算法的复杂度为O(logN),故此方法也是。

时间复杂度:O(logN),空间复杂度:O(1)。

其实这道题和欧几里得的思想并没有太大关系···只是形式上一样···以后遇到数论题要多推一下式子···

代码:

#include <stdio.h>
#ifdef WIN32
#define OTL "%I64d"
#else
#define OTL "%lld"
#endif
#define ll long long
ll p, q, ans; void Deal( ll p, ll q ) {
if ( q == ) return;
ans += p / q;
Deal( q, p % q );
} int main() {
//freopen( "resistance.in", "r", stdin );
//freopen( "resistance.out", "w", stdout );
scanf( OTL OTL, &p, &q );
Deal( p, q );
printf( OTL, ans );
return ;
}

最新文章

  1. 避免重复造轮子的UI自动化测试框架开发
  2. Java时间日期格式转换
  3. How to do logging in C# with log4net
  4. hive 中 union all
  5. Ubuntu系统的修改Hosts
  6. flex 图片旋转(解决公转和自转问题)
  7. sqlserver 查找某个字符在字符串中第N次出现的位置
  8. 【C#网络基础】C# get post请求
  9. IOS SDK相机的详细解释/画廊(默认+他们的高清摄像头接口)
  10. bppm与AD域集成
  11. MYSQL数据库学习十六 安全性机制
  12. Jenkins 2.x版本修改启动端口号
  13. crontab计划任务实例
  14. qemu中的内存管理
  15. k8s常用命令
  16. 安装FP
  17. (转)每天一个linux命令(21):find命令之xargs
  18. **CI创建类库(创建自己的工具类等)
  19. Java并发编程的艺术(七)——Executors
  20. ionic中generate page后module.ts报错的解决办法

热门文章

  1. 一步一步教你用IntelliJ IDEA 搭建SSM框架(1)
  2. Ubuntu下命令行访问网站
  3. 计算机应用第三次作业:自动开机自动关机 常用DOS命令 关于文件文件夹
  4. DD命令做备份和恢复
  5. 洛谷 1571 眼红的Medusa
  6. golang 函数的特殊用法
  7. Word 借助VBA一键实现插入交叉引用
  8. hdu 5441
  9. Win7里IIS7部署WebService
  10. poj 3107 Godfather(树的重心)