实验题目

在8枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道假币与真币相比较轻还是重。可以通过一架天平来任意比较两组硬币,设计一个高效的算法来检测这枚假币。

实验目的

1.深刻理解并掌握减治法的设计思想;
2.提高应用减治法设计算法的技能;
3.理解这样一个观点:建立正确的模型对于问题的求解释非常重要的。

实验要求

1.设计减治法实现8枚硬币问题;
2.设计实验程序,考察用减治法技术设计的算法是否高效;
3.扩展算法,使之能处理n枚硬币中有一枚假币的问题。

算法设计与实现

从八枚硬币中任取六枚a,b,c,d,e,fa,b,c,d,e,fa,b,c,d,e,f,在天平两端各放三枚进行比较。假设a,b,ca,b,ca,b,c三枚放在天平的一端,d,e,fd,e,fd,e,f三枚放在天平的另一端,可能出现三种比较结果:
⑴a+b+c>d+e+f⑴a+b+c>d+e+f⑴ a+b+c>d+e+f
⑵a+b+c=d+e+f⑵a+b+c=d+e+f⑵ a+b+c=d+e+f
⑶a+b+c<d+e+f⑶a+b+c<d+e+f⑶ a+b+c
若a+b+c>d+e+fa+b+c>d+e+fa+b+c>d+e+f,可以肯定这六枚硬币中必有一枚为假币,同时也说明,g,hg,hg,h为真币。这时可将天平两端各去掉一枚硬币,假设去掉ccc和f" role="presentation" style="position: relative;">fff,同时将天平两端的硬币各换一枚,假设硬币bbb和e" role="presentation" style="position: relative;">eee作了互换,然后进行第二次比较,比较的结果同样可能有三种:
① a+e>d+ba+e>d+ba+e>d+b: 这种情况表明天平两端去掉硬币c,fc,fc,f且硬币b,eb,eb,e互换后,天平两端的轻重关系保持不变,从而说明了假币必然是a,da,da,d中的一个,这时我们只要用一枚真币(例如hhh)和a" role="presentation" style="position: relative;">aaa进行比较,就能找出假币。若a>ha>ha>h,则aaa是较重的假币;若a=h" role="presentation" style="position: relative;">a=ha=ha=h,则ddd为较轻的假币;不可能出现a" role="presentation" style="position: relative;">aaa
② a+e=d+ba+e=d+ba+e=d+b:此时天平两端由不平衡变为平衡,表明假币一定在去掉的两枚硬币c,fc,fc,f中,同样用一枚真币(例如hhh)和c" role="presentation" style="position: relative;">ccc进行比较,若c>hc>hc>h,则ccc是较重的假币;若c=h" role="presentation" style="position: relative;">c=hc=hc=h,则fff为较轻的假币;不可能出现c" role="presentation" style="position: relative;">ccc
③a+e<d+ba+e<d+b a+e: 此时表明由于两枚硬币b,eb,eb,e的对换,引起了两端轻重关系的改变,那么可以肯定bbb或e" role="presentation" style="position: relative;">eee中有一枚是假币,同样用一枚真币(例如hhh)和b" role="presentation" style="position: relative;">bbb进行比较,若b>hb>hb>h,则bbb是较重的假币;若b=h" role="presentation" style="position: relative;">b=hb=hb=h,则eee为较轻的假币;不可能出现b" role="presentation" style="position: relative;">bbb
对于结果(2)和(3)的情况,可按照上述方法作类似的分析。
下图给出了判定过程,图中大写字母HHH和L" role="presentation" style="position: relative;">LLL分别表示假币较其它真币重或轻,边线旁边给出的是天平的状态。八枚硬币中,每一枚硬币都可能是或轻或重的假币,因此共有16种结果,反映在树中,则有16个叶子结点,从下图中可看出,每种结果都需要经过三次比较才能得到。


在n枚硬币问题中,同样应用减治法的思想,将硬币分为3堆,则每堆的硬币数量为 n/3 ,但是这在 n%3==0 的情况下才能成立,所以我们将 n 枚硬币分为 3 堆加 1 个余数堆(余数堆可能为0),则可分为如下(n-n%3)/3,(n-n%3)/3,(n-n%3)/3,n%3。
逻辑流程:
1. 首先获取真币,通过从数组中随机取三枚硬币,互相比较,相等的两枚为真币,任意取一枚作为真币记录数组下标。
2. 判断n中的硬币数量,如果n>2则执行3,否则执行6.
3. 将n分为上图的四堆,拿 a 和 b 比较,如果 a == b ,则 假币在 c 或 d 中。否则假币在 a 或 b 中。
4. 如果 a == b,则拿 a 和 c 比较。如果 a == c,则假币在d(余数堆)中。将 d 再次 执行流程2,并且n=n%3。如果不等,则假币在 c 中,将 c 再次 执行流程2,并且n=(n-n%3)/3。
5. 如果 a != b,则拿 a 和 c 比较。如果 a == c,则假币在b中,将 b 再次 执行流程2,并且n=(n-n%3)/3。如果不等,则假币在 a 中,将 a 再次 执行流程 2,并且n=(n-n%3)/3。
6. 如果n==2,则将两枚硬币与真的硬币(通过 数组下标 )进行比较,不同的为假币,输出结果,结束。
7. 如果n==1,则该硬币就是假币,输出结果结束。
程序源码:

#include<iostream>
using namespace std;  //函数声明
void eightcoin(int arr[]);
void compare(int a, int b,int real, int index1,int index2);
void print(int fake, int real, int i);  int main()
{    int arr[8];  //这里输入a、b、c、d、e、f、g、h的重量  cout<<"请输入八枚硬币:"<<endl;  for(int i = 0; i < 8; i++)  {  cin>>arr[i];  }  eightcoin(arr);   return 0;
}  void eightcoin(int arr[])
{  //取数组中的前6个元素分为两组进行比较abc,def  //会有a+b+c > d+e+f | a+b+c == d+e+f | a+b+c < d+e+f 三种情况  int abc = arr[0] + arr[1] + arr[2];  int def = arr[3] + arr[4] + arr[5];  int a = arr[0];  int b = arr[1];  int c = arr[2];  int d = arr[3];  int e = arr[4];  int f = arr[5];  int g = arr[6];  int h = arr[7];  if(abc > def)        //6枚硬币必有一枚假币,g,h为真币  {  if((a + e) > (d + b))    //去掉c,f,且b,e互换后,没有引起天平变化,说明假币必然是a,d中的一个  {  compare(a,d,g,0,3);  }  else if((a + e) == (d + b))  {  compare(c,f,g,2,5);  }  else  {  compare(b,e,g,1,4);  }  }  else if(abc == def) //假币在g,h之中,最好状态  {  if(g == a)  {  print(h,g,7);  }   else  {  print(g,h,6);  } }  else                //abc < def 这两组存在一枚假币,g,h为真币  {  if((a + e) > (d + b))  {  compare(b,e,g,1,4);  }  else if((a + e) == (d + b))  {  compare(c,f,g,2,5);  }  else  {  compare(a,d,g,0,3);  }  }  }
/**
* 取出可能有一枚假币的两枚假币,作为参数a和参数b
* real表示真币的重量,index1为第一枚硬币的下标,index2为第二枚硬币的下标
*/
void compare(int a, int b,int real, int index1,int index2)
{  if(a == real)  {  print(b,real,index2);  }  else  {  print(a,real,index1);  }
}
void print(int fake, int real, int i)
{  if(fake > real)  {  cout<<"位置在:"<<(i + 1)<<"是假币!"<<"且偏重!";  }  else {  cout<<"位置在:"<<(i + 1)<<"是假币!"<<"且偏轻!";  }
}  

实验结果与分析

1.实验结果

2.实验分析

减治法是把一个大问题划分为若干个小问题,但是这些子问题不需要分别 ,只需要求解其中的一个子问题,因而也无须对子问题的解进行合并,这样大大提高了算法的效率。
在八枚硬币问题中,应用减治法,将问题一分为二,这样只需要3次比较便能解决问题。
对于n枚硬币问题,同样可以用减治法处理,采用分治和递归的方法逐步接近问题的解。

算法设计与分析之八枚硬币问题相关推荐

  1. 算法设计与分析: 4-11 硬币找钱问题

    4-11 硬币找钱问题 问题描述 设有 6 种不同面值的硬币,各硬币的面值分别为 5 分,1 角,2 角,5 角,1 元,2 元. 现要用这些面值的硬币来购物和找钱.购物时可以使用的各种面值的硬币个数 ...

  2. C/C++ 算法设计与分析实验报告

    算法设计与分析实验报告 算法实验整体框架的构建 菜单代码块 选择函数代码块 主函数代码块 实验模块Ⅰ:算法分析基础--Fibonacci序列问题 实验解析 Fibonacci序列问题代码块 实验模块Ⅱ ...

  3. 【算法设计与分析】经典常考三十三道例题AC代码

    ❥小虾目前大三,我校在大一下开设<数据结构>这门课,大二上开了<算法设计与分析>这门课,很庆幸这两门课的上机考试总成绩一门100,一门99,最后总分也都90+.下文会给出机试的 ...

  4. 算法设计与分析------蛮力法

    算法设计与分析------蛮力法(c语言) 一.蛮力法(穷举法 枚举法) 1.定义 2.蛮力法使用情况 3.蛮力法的优点 4.蛮力法的缺点 5.采用蛮力法设计算法的2类: 6.简单选择排序和冒泡排序 ...

  5. 算法设计与分析课后总结

    算法设计与分析课后总结 算法设计与分析 第1章 算法设计基础 课后习题 第二章算法分析基础 课后习题 1.考虑下面算法,回答下列问题,算法完成什么功能?算法的基本语句时什么?基本语句执行了多少次? 2 ...

  6. 【算法设计与分析】求解查找假币问题

    文章目录 前言 题目描述 解题思路 参考代码 总结 前言 <算法设计与分析>的实验,稍微记录一下,欢迎讨论. 题目描述 编写一个实验程序查找假币问题.有n(n>3)个硬币,其中有一个 ...

  7. 算法设计与分析(电子科技大学)(上)算法基础和贪心算法

    算法分析与设计 引论 (1)理解算法和程序的差别 (2)理解判断问题和优化问题这两类计算问题 1.理解指数增长的规模 2.理解渐进表达式 掌握渐进符号Ο.Θ.Ω的含义,能判断一个函数属于哪个渐近增长阶 ...

  8. 算法设计与分析基础-笔记-上

    算法设计与分析基础 绪论 什么是算法 一系列解决问题的明确指令,对于符合一定规范的输入,能够在有限的时间内获得要求的输出. 例子:最大公约数:俩个不全为0 的非负整数 m m m和 n n n的最大公 ...

  9. 算法设计与分析课程的时间空间复杂度

    算法设计与分析课程的时间空间复杂度: 总结 算法 时间复杂度 空间复杂度 说明 Hanoi $ O(2^n) $ $ O(n) $ 递归使用 会场安排问题 \(O(nlogn)\) \(O(n)\) ...

最新文章

  1. JZOJ 3.10 1540——岛屿
  2. php -- PDO事务处理
  3. 数据库管理工具 FileMaker Pro 17 Advanced v17.0.4.400中文版
  4. 玩转html5画图 - TimeLangoliers - 博客园
  5. 爬虫-request库-get请求
  6. linux系统获取光盘信息api,在Visual C#中运用API函数获取系统信息
  7. 专题_期权交易必备知识
  8. C语言需要什么程序翻译,c语言怎么翻译? 程序怎么运行?
  9. android 11 版本更新内容,android 11怎么更新 android 11更新方法
  10. angular学习笔记
  11. 如何使用Omni Remover Mac版释放Mac上的空间
  12. Git - Merge: refusing to merge unrelated histories
  13. 【VRP】基于matlab遗传算法求解出租车网约车接送客车辆路径规划问题【含Matlab源码 YC003期】
  14. matlab均值滤波代码6,均值滤波matlab程序代码
  15. openg离线包_高级openg 混合,一个完整程序
  16. SAP固定资产的几个日期
  17. 超简单的—CSDN去水印方法——实用小技巧分享(01)
  18. 【附源码】手写一个Ico生成器
  19. Bongo Cat 小猫咪自制全键盘版本 养一只超可爱的小猫
  20. html 关闭当前tab页面,js关闭浏览器的tab页(兼容)

热门文章

  1. 对SSM框架中Dao层,Mapper层,controller层,service层,model层,entity层等层的理解
  2. 大数据上云存算分离演进思考与实践
  3. ZZULIOJ 1244:学长被狗追了!
  4. [case3]聊聊系统设计中的trade-off
  5. 在LINUX用玩英杰传曹操传
  6. L1-051 打折 (5分)(C语言)
  7. 基于51单片机电子密码锁门禁开关设计全套资料
  8. 使用css制作永动的动画
  9. 你站在桥上看风景,看风景的人在楼上看你
  10. 删除指定文件夹以及文件下的文件