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


前言

《算法设计与分析》的实验,稍微记录一下,欢迎讨论。


题目描述

编写一个实验程序查找假币问题。有n(n>3)个硬币,其中有一个假币,且假币较轻,采用天平称重方式找到这个假币,并给出操作步骤。


解题思路

假设n个硬币编号为0~n-1,采用数组data存放所有硬币的重量。假设真币重量为2、假币重量为1,假币采用随机方式产生。采用二分法实现查找算法。


参考代码

#include <iostream>
#include <ctime>
#include <cstdlib> // 包含产生随机数的库函数
#define MAX 1000
using namespace std;

int data[MAX];

int sum(int low, int high) { // 求data[low..high]的重量
	int sum = 0;
	for(int i = low; i <= high; i++) sum += data[i];
	return sum;
}

int solve(int low, int high) {
	if(low == high) return low; // 只有一个硬币 
	if(low == high - 1) { // 只有两个硬币 
		if(data[low] < data[high]) return low;
		else return high;
	}
	int mid = (low + high) / 2;
	int sum1, sum2;
	if((high - low + 1) % 2 == 0) { // 区间内硬币个数为偶数
		sum1 = sum(low, mid);
		sum2 = sum(mid + 1, high);
		printf("硬币%d-%d和硬币%d-%d称重一次:", low, mid, mid + 1, high);
	} else { // 区间内硬币个数为奇数
		sum1 = sum(low, mid - 1);
		sum1 = sum(mid + 1, high);
		printf("硬币%d-%d和硬币%d-%d称重一次:", low, mid - 1, mid + 1, high);
	}
	if(sum1 == sum2) {
		printf("两者重量相同。\n");
		return mid;
	} else if(sum1 < sum2) { // 假币在左区间 
		printf("前者重量轻。\n");
		if((high - low + 1) % 2 == 0) return solve(low, mid); // 区间内硬币个数为偶数 
		else return solve(low, mid - 1); // 区间内硬币个数为奇数 
	} else { // 假币在右区间 
		printf("后者重量轻。\n");
		return solve(mid + 1, high);
	}
}

int main (void) {
	int n = 12; // 假设有12个硬币
	for(int i = 0; i < n; i++) data[i] = 2;
	srand((unsigned)time(NULL)); // 随机数种子 
	data[rand() % n] = 1;  // 随机生成一个假币 
	printf("求解过程:\n");
	printf("硬币%d是假币。\n", solve(0, n - 1));
	return 0;
}

总结

这道题还可以采用三分法求解。同时还得看清题意,到底有几个假币,假币比真币重还是轻……其次是看清要用什么算法或者说限制时间复杂度是多少。不然的话这道题其实可以用嵌套for循环遍历出来的。

  • 11
    点赞
  • 60
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值