HPUOJ 题目1079 假币问题(三分)

57 篇文章 1 订阅

1079: 假币问题

时间限制: 1 Sec   内存限制: 128 MB
提交: 7   解决: 1
[ 提交][ 状态][ 讨论版]

题目描述

居然有假币!!! 
事情是这样的,现在猪肉涨了,但是农民的工资却不见涨啊,没钱怎么买猪肉啊。老王这就去买猪肉,结果找来的零钱中有假币!!!可惜老王一不小心把它混进了一堆真币里面去了。现在知道假币的重量比真币的质量要轻。给你一个天平,请用最快的时间把那个可恶的假币找出来。

输入

输入有多行,每一行的值为硬币的数目n,1≤n≤2^30,输入0结束程序

输出

最少要称多少次一定能把那个假币找出来。输出对应输入行数.

样例输入

3120

样例输出

13

提示

示例1中共有3枚硬币,所以任意取2个放天平上称量一下。 

因为假币的重量比较轻。 

如果天平不平衡,则较轻的那枚就是假币。 

如果天平平衡,则说明这两枚硬币都是真的,而剩下那枚是假币。

来源

[ 提交][ 状态][ 讨论版]
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
三分法是一种数值计算方法,用于求解一元函数的极值或者方程的根。对于假币问题,可以使用三分法来判断一个硬币是否为真币。 以下是一个基于三分法的假币检测的 C 语言程序示例: ```c #include <stdio.h> // 模拟硬币重量函数 double Weight(int n) { if (n <= 0) return 0; if (n == 1) return 1.0; if (n % 2 == 0) return Weight(n / 2) + Weight(n / 2); else return Weight(n / 2) + Weight(n / 2 + 1); } // 三分法求解假币问题 int FindFakeCoin(int left, int right) { int mid1, mid2; double w1, w2, w3; while (left < right) { mid1 = left + (right - left) / 3; mid2 = right - (right - left) / 3; w1 = Weight(left); w2 = Weight(mid1); w3 = Weight(mid2); if (w1 == w2 && w2 == w3) return -1; // 三个硬币重量相等,无法判断 else if (w1 < w2 && w2 < w3) left = mid1 + 1; // 假币在 mid2 的右边 else if (w1 > w2 && w2 > w3) right = mid2 - 1; // 假币在 mid1 的左边 else { left = mid1 + 1; right = mid2 - 1; } // 假币在 mid1 和 mid2 之间 } return left; } int main() { int n; printf("请输入硬币数量:"); scanf("%d", &n); int fake = FindFakeCoin(1, n); if (fake == -1) printf("无法判断硬币真假!\n"); else printf("第 %d 枚硬币为假币!\n", fake); return 0; } ``` 在程序中,我们定义了一个模拟硬币重量的函数 `Weight(int n)`,用于计算第 n 枚硬币的重量。对于假币问题,我们可以假设真币和假币的重量相差 1,然后使用递归的方式模拟硬币的重量。 在 `FindFakeCoin(int left, int right)` 函数中,我们使用三分法对硬币进行判断。首先,我们将硬币分成三个部分,分别为 `left` 到 `mid1`、`mid1` 到 `mid2`、`mid2` 到 `right`。然后,我们分别计算这三个部分的重量,并进行比较。如果三个部分的重量相等,说明无法判断,返回 -1;如果重量递增,说明假币在 `mid2` 的右边;如果重量递减,说明假币在 `mid1` 的左边;否则,假币在 `mid1` 和 `mid2` 之间。最后,我们将 `left` 和 `right` 更新到新的位置,并继续进行判断,直到 `left` 和 `right` 相等。 在 `main()` 函数中,我们输入硬币的数量,然后调用 `FindFakeCoin()` 函数进行判断。如果返回值为 -1,说明无法判断;否则,返回的值就是假币的位置。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值