2017年软件设计师上半场下午题目

【说明】
假币问题:有n枚硬币,其中有一枚是假币,已知假币的重量较轻。现只有一个天平,要求用尽量少的比较次数找出这枚假币。
【分析问题】
将n枚硬币分成相等的两部分:
(1)当n为偶数时,将前后两部分,即1…n/2和n/2+1…n,放在天平的两端,较轻的一端里有假币,继续在较轻的这部分硬币中用同样的方法找出假币;
(2)当n为奇数时,将前后两部分,即1…(n -1)/2和(n+1)/2+1…n,放在天平的两端,较轻的一端里有假币,继续在较轻的这部分硬币中用同样的方法找出假币;若两端重量相等,则中间的硬币,即第 (n+1)/2枚硬币是假币。
【C代码】
下面是算法的C语言实现,其中:
coins[]:硬币数组
first,last:当前考虑的硬币数组中的第一个和最后一个下标。

答案

#include<stdio.h>int getCounterfeitCoin(int coins[], int first, int last)
{int firstSum = 0, lastSum = 0;int i;if (first == last - 1) // 只剩两枚硬币{// 返回较轻的那个索引if (coins[first] < coins[last]) return first;return last;}if ((last - first + 1) % 2 == 0) // 偶数枚硬币{for (i = first; i < first + (last - first) / 2 + 1; ++ i) // 第一空可以直接看题目题目中直接把偶数的时候区间为1...n/2给出来了,也可以看下面的那个循环的i为first+(last - first)/2+1{firstSum += coins[i];}for (i = first + (last - first) / 2 + 1; i < last + 1; ++ i){lastSum += coins[i];}if (firstSum < lastSum) // 第二空位置 根据题目描述选择更轻的那一边{return getCounterfeitCoin(coins, first, first + (last - first)/2);}else {return getCounterfeitCoin(coins, first + (last - first)/2 + 1, last);}}else  // 奇数枚硬币{for(i = first; i < first + (last - first)/2; ++ i) firstSum += coins[i];for(i = first + (last - first)/2 + 1; i < last + 1; ++ i) lastSum += coins[i];if (firstSum < lastSum) return getCounterfeitCoin(coins, first, first + (last - first)/2 - 1);else if (firstSum > lastSum) return getCounterfeitCoin(coins, first + (last - first)/2 - 1, last);else return coins[first + (last - first) / 2]; // 第三空位置,当硬币数量为奇数的时候有三种情况,比偶数多的一个情况为,就是这个奇数区间的中位数}
}

算法采用了(分治)设计策略。 // 分治分而治之,这个题的具体算法名称叫做二分,二分就是分治的经典运用。

时间复杂度为O(logn)。// 倒也不需要怎么详细的计算,首先根据是分支算法,所以时间复杂度里面一定有logn,分支的特点就是把O(n)的降为O(logn),这个题如果采取暴力的话就是O(n)

若输入的硬币数为30,则最少的比较次数为(2),最多的比价次数为(4)。
最少的情况为:因为30位偶数,所以至少要被分一次,然后成为奇数之后,那个假币就是奇数的中位数,所以只需要2次。
最多的情况为:floor(log2(30)) = 4

假币问题:有n枚硬币,其中有一枚是假币,已知假币的重量较轻。现只有一个天平,要求用尽量少的比较次数找出这枚假币。相关推荐

  1. 有一堆共n枚硬币,其中一枚是假币,外观上无法区分,只知道假币的重量稍轻。要求仅使用一个天平,使用最少的重量比较次数找出假硬币。

    有一堆共n枚硬币,其中一枚是假币,外观上无法区分,只知道假币的重量稍轻.要求仅使用一个天平,使用最少的重量比较次数找出假硬币. 将n个硬币分成数量相同的两堆,如果n为偶数,每堆的硬币个数为n/2: 如 ...

  2. Python(分治算法)问题 A: 找出伪币_给你一个装有n枚硬币的袋子。n枚硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。你的任务是找出这枚伪造的硬币。

    问题 A: 找出伪币 题目描述 给你一个装有n枚硬币的袋子. n枚硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些. 你的任务是找出这枚伪造的硬币. 输入 测试数据有多行,第一行是金币的数量 ...

  3. 【算法设计与分析】8枚硬币及n枚硬币问题

    问题描述 在8枚外观相同的硬币中,有一枚是假币,并且已知假币和真币的重量不同,但不知假币是轻还是重,用天平来任意比较两组硬币. 8枚硬币问题 1.把8枚硬币分为3.3.2三个部分 2.先判断前两个部分 ...

  4. 算法——从9个硬币中找出其中的1枚假硬币

    9个硬币,其中有一个硬币是假的(不知道其比真的硬币轻或重),问:最少称多少次能找出这枚假硬币? 首先将硬币3等分: 第1次称重 任意两份进行,有两种情况: 第2次称重 以第一次称重不等的那组为基础,即 ...

  5. 12枚硬币称重问题(面试)

    问题描述: 12枚硬币,其中11枚真币1枚假币,现有一架天平,最少称多少次可以找出这枚假币并且知道假币和真币的相对重量. 答案是三次,称重过程描述如下. 第一步:分组,分三组,1 2 3 4为一组,5 ...

  6. (2013.05.05)N枚硬币找1枚假币

    N枚硬币找1枚假币 ――Neicole (2013.05.05) 0. 问题描述 共有N枚硬币,一个天平,在这N枚硬币中有一枚假币,设法找出该枚假币. 1. 原理示例(减治法) 概要: 如上图所示,假 ...

  7. n枚硬币问题(假币问题)——分治法(减治法)

    1.8枚硬币问题 在8枚外观相同的硬币中,有一枚是假币,并且已知假币与真币的重量不同,但不知道的是假币与真币相比较是轻还是重.可以通过一架天平来比较两组硬币: 减治法将原问题一分为三,8枚硬币分别表示 ...

  8. Java实现8枚硬币问题(减治法)

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

  9. 27枚硬币,找出较重的一个-Python

    称硬币问题-Python: 一. 问题描述 现在有27枚硬币,其中有一枚假币,假币跟真币长得一摸一样,但是稍微重一些.摆在桌上有一个称重天平,要求用最小的次数找出假币,并写出算法代码. 二. 解题思路 ...

最新文章

  1. 查看docker容器日志
  2. 模块(sys/os/序列化模块)
  3. python fortran混合编程_python调用fortran模块
  4. java类的聚合 组合定义_Java里组合和聚合的概念及其实现
  5. 如何在 Linux 中使用 AppImage
  6. python程序设计实训报告-Python编程实践(1)
  7. 一文掌握秩和比综合评价法
  8. pyqt5优化美化界面代码
  9. (全过程)如何制作论坛网站,怎样免费制作论坛,制作论坛教程
  10. kali-2019.4中文乱码问题的解决
  11. destoon网站转移空间教程
  12. 电工电子学习笔记----1.电阻、电容、阻抗、容抗复习巩固
  13. 身边的礼仪---整理版
  14. V8引擎如何回收内存以及如何优化
  15. linux 命令行退出某条命令
  16. 即时通讯环信IM的集成使用
  17. vert.x最新官网书籍下载
  18. Ubuntu 软件仓库源
  19. Redis分布式部署
  20. ThinkPad适不适合计算机专业,thinkpad适合什么人用

热门文章

  1. 狄兰·托马斯诗合集▷Do not go gentle into that good night
  2. web前端基础——rotate实现旋转效果
  3. 解决Mac能接受qq消息但打不开网页的问题
  4. 【★★★所有A42JV 和 K42JV的用户和未来用户联合起来~!!让华硕知道不能忽视我们~!】...
  5. java实现发布订阅
  6. 分治法之图解最大子序列和
  7. php小程序 100行左右,微信小程序 左右分类滚动列表
  8. 怎么看待SEO?新型SEO与传统SEO对比优势?
  9. 文件管理工具,如何批量将文件名改成对应文件夹的名称
  10. 2021年茶艺师(初级)模拟考试及茶艺师(初级)模拟考试题