分治法找假币

来源:互联网 发布:知否之风的下一句 编辑:程序博客网 时间:2024/06/05 04:34

所谓分治法,就是将复杂而麻烦的大问题分解为一个个计算量比较小的小问题,通过求解小问题,而最终得到大问题的解

问:有n个硬币,其中有一个假币质量较轻,通过一个天平将假币挑出

答:将假币分成两份去称,轻的那一半包含假币,将轻的那一半又分为两份,接着称,直到剩下最后两枚,轻的那一枚即为假币

tip:考虑到硬币个数为奇数的情况,照样分为两半,剩下一个多余的,如果两半等重,多余的那枚即为假币,否则继续处理剩下两半。


代码如下:

//分治法找假币#include<iostream>#include<cstdlib>using namespace std;int FakeCoin(int Coins[], int low, int high){if ((high - low) == 1)return Coins[high] < Coins[low] ? high : low;if((high-low)%2==1)//硬币总数为偶数{cout << "偶数" << endl;int mid = (low + high) / 2;int left = 0, right = 0;for (int i = 0; i <= mid; i++)left += Coins[i];for (int i = mid + 1; i <= high; i++)right += Coins[i];if (left < right){cout << "左 " << low <<" "<<high<< endl;return FakeCoin(Coins, low, mid);}else{cout << "右" << mid + 1 << " " << high << endl;return FakeCoin(Coins, mid + 1, high);}}else//硬币总数为奇数{cout << "奇数" << endl;int mid = (low + high) / 2;int left = 0, right = 0;for (int i = 0; i < mid; i++)left += Coins[i];for (int i = mid + 1; i <= high; i++)right += Coins[i];if (left == right){cout << "正好在中间" << endl;cout << mid << endl;return mid;}else if (left < right){cout << "左" << low << " " << mid << endl;return FakeCoin(Coins, low, mid);}else{cout << "右" << mid << " " << high << endl;return FakeCoin(Coins, mid, high);}}}int main(){int n;int Coins[25] = { 2,2,2,2,2,2,2,2,2,2,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2 };cout << FakeCoin(Coins, 0, 24);system("pause");return 0;}