题目

一个袋子里有30个银币,其中一枚是假币,并且假币和真币一模一样,肉眼很难分辨,目前只知道假币比真币重量轻一点。
请问,如何区分出假币?

分析

首先,分析一下寻找假币问题,采用递归分治的思想求解。

  1. 首先为每个银币编号,然后将所有的银币等分为两份,放在天平的两边。这样就将区分30个银币的问题变为区别两堆银币的问题。
  2. 因为假币分量较轻,因此天平较轻的一侧中一定包含假币。
  3. 再将较轻的一侧中银币等分为两份,重复上述做法。
  4. 直到剩下两枚银币,便可用天平直接找出假银币。

分治算法思想

分治算法的基本思想是将一个计算复杂的问题分为若干个规模较小、计算简单的小问题来进行求解,然后综合各个小问题,得到最终问题的答案。

执行过程如下:

  1. 对于一个规模为N的问题,若该问题可以容易的解决(比如说规模N较小),则直接解决,否则执行下面的步骤;
  2. 将该问题分解为M个规模较小的子问题,这些子问题应该互相独立,并且与原问题形式相同;
  3. 递归求解各个子问题;
  4. 然后将各个子问题的解合并得到原问题的解;

使用分治算法要求待求解的问题能够化简为若干个小规模的相同问题,通过逐步划分,达到一个易于求解的阶段而直接进行求解。然后再程序中使用递归算法进行求解。

代码

#include <iostream>
#include <cstdlib>using namespace std;const int MAXNUM = 30;int falseCoin(int weight[], int lhs, int rhs)
{if (lhs == rhs)return lhs + 1;//如果只剩下两个银币,则较轻的那个便是假币else if (lhs == (rhs - 1)){return weight[lhs] < weight[rhs] ? lhs + 1 : rhs + 1;}int lsum = 0, rsum = 0;//如果偶数个银币,则比较两等份if ((rhs - lhs + 1) % 2 == 0){for (int i = lhs; i < (lhs + (rhs - lhs + 1) / 2); i++){lsum += weight[i];}for (int j = lhs + (rhs - lhs + 1) / 2; j <= rhs; j++){rsum += weight[j];}//左右两份等重,则无假币if (lsum == rsum)return -1;elsereturn (lsum < rsum) ? falseCoin(weight, lhs, lhs + (rhs - lhs) / 2) : falseCoin(weight, lhs + (rhs - lhs) / 2 + 1, rhs);}//如果奇数个银币,则比较除中间银币外的两等份else if ((rhs - lhs + 1) % 2 != 0){for (int i = lhs; i < (lhs + (rhs - lhs) / 2); i++){lsum += weight[i];}for (int j = (lhs + (rhs - lhs) / 2 + 1); j <= rhs; j++){rsum += weight[j];}//左右两份等重,则无假币if (lsum == rsum && weight[lhs] == weight[lhs + (rhs - lhs) / 2])return -1;//如果两份等重,中间银币较轻,则中间银币为假币else if (lsum == rsum && weight[lhs] > weight[lhs + (rhs - lhs) / 2])return lhs + (rhs - lhs) / 2 + 1;//否则,返回较轻那份中的假币elsereturn (lsum < rsum) ? falseCoin(weight, lhs, lhs + (rhs - lhs) / 2 - 1) : falseCoin(weight, lhs + (rhs - lhs) / 2 + 1, rhs);}
}int main()
{int weight[MAXNUM];int n;while (cin >> n){for (int i = 0; i < n; i++)cin >> weight[i];int falsePos = falseCoin(weight, 0, n - 1);if (falsePos != -1)cout << "第" << falsePos << "个银币为假币!" << endl;elsecout << "无假币!" << endl;}//whilesystem("pause");return 0;
}

GitHub代码下载

3_寻找假币问题(分治法)相关推荐

  1. 寻找中项和第k小元素c语言,分治法第k小元素poj2104.ppt

    分治法第k小元素poj2104 第六章 分 治 6.1 引言 分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之. 战略 算法设计技术 划分--治理- ...

  2. 分治法实现寻找数组最大最小值

    分治法实现寻找数组最大最小值 大致思路 我们拿到一个长度为K的一维数组,想要在短时间内进行最大最小值的查找,第一种想法就是现将数组进行排序,这样首末的元素分别是最小和最大的元素.排序算法中,快速排序. ...

  3. 用分治法设计一个算法,在数组A中寻找最大元素和最小元素 Java代码

    算法分析与设计作业-- 用分治法设计一个算法,在数组A中寻找最大元素和最小元素 public class b1113 {static int min=Integer.MAX_VALUE;static ...

  4. 分治法实验-寻找第k小元素

    问题描述 随机生成含有n个不同元素的数组L(n≥10000),要求找出第k小的元素(k≤n),完成下面的任务: (1)设计一个基于排序选择算法程序,编程调试正确(排序算法自己确定). (2)设计一个时 ...

  5. Python课后作业 2. 分治法找假币 ----(第八次作业)

    文章目录 前引闲聊 原题题目 代码实现(分治法 真的麻了) 代码实现(一次遍历) 提交结果 前引闲聊 我说实话 这道题真的好无聊好无聊好无聊 我就这样说嘛 这道题有好蠢 我们只需要一次遍历 就是如果数 ...

  6. 动态规划和分治法,贪心算法以及递归的再一次深刻理解和体会

    每次体会算法都有新的感觉,刷题越多,对算法的理解感觉也就越深刻. 下面我们来重新体会下分治法,动态规划,贪心法,递归的理解. 1.分治法: 将问题分成单独的阶段,每个阶段互相不干扰很独立,如10米长的 ...

  7. 程序员的算法课(13)-分治法

    一.什么是分治 [百度百科]分治法((Divide and Conquer))可以通俗的解释为:把一片领土分解,分解为若干块小部分,然后一块块地占领征服,被分解的可以是不同的政治派别或是其他什么,然后 ...

  8. c++分治法求最大最小值实现_你所不了解的分治算法

    本文通过讲解3个基本问题的应用,提供了分治算法设计范式的实践.第一个例子是对数组中的逆序对进行计数的算法(第3.2节).这个问题与测量两个有序列表的相似性有关,适用于根据自己的知识向其他人按照他们的偏 ...

  9. 分治法求最大和最小值

    例题:金块问题 老板有一袋金块(共n块,n是2的幂(n>=2) ),最优秀的员工得到其中最重的一块,最差的员工得到其中最轻的一块.假设有一台比较重量的仪器,请你用最少的比较次数找出最重和最轻的金 ...

  10. 分治法--处理数列问题

    # 分治法–处理数列问题 前言 最近学了分治法,我发现分治法在求一组数列的某些数据时有着很简洁的技巧.分治算法基本思想–"分"."治"."合" ...

最新文章

  1. 10个重要的Linux ps命令实战
  2. dockerfile构建nginx服务
  3. 【总结】一文了解所有的机器学习评价指标
  4. PHP预防XSS攻击,ajax跨域攻击的方法
  5. 机器学习基础-最近邻规则分类 KNN (K-Nearest Neighbor)-11
  6. IT巨头互掐云存储:Dropbox能否一马当先
  7. Flutter学习 — 设计基础
  8. 两道关于前缀和的算法题
  9. 如何用python计算圆周率_使用MicroPython计算任意位数圆周率
  10. 计算机高特效吃鸡游戏主机配置单,畅玩主流游戏吃鸡LOL组装电脑配置清单
  11. 如何在自己行业内放大和增加收入
  12. 使用C语言播放一首音乐
  13. 青龙面板2.8版本+Ninja 保姆级 服务器安装jd代挂教程——(二)
  14. 将VMware工作站最小化至托盘栏
  15. 人事不易,成事更不易
  16. AIR2.0 打开exe
  17. FTP+VSFTPD
  18. 基于 Android 系统手机通讯录管理软件【100010322】
  19. 我说CMMI2.0之管理性能和度量数据
  20. Echarts 世界地图

热门文章

  1. 阿里云数据迁移工具解决方案:腾讯云迁移到阿里云
  2. 怎么将flv格式转换成mp4,四个步骤完成转换
  3. 模拟人生畅玩版正在连接至服务器,模拟人生™:畅玩版无法连接服务器如何解决...
  4. 生物与环境 —— 生命的力量
  5. mysql distinct count_MySQL中distinct和count(*)的使用方法比较
  6. 计算机专业考研2021,2021考研:计算机专业考研方向有哪些?
  7. 北京网友加拨河北保定区号电话抢票引争议
  8. linux 判断是否root权限,Android adb 判断是否有root权限
  9. requests 模块获取免费的代理并检测代理 IP 是否有效!
  10. java中怎样实现登陆界面_JAVA登陆界面的实现(一)