假币问题(二分法与三分法实现)
生活随笔
收集整理的這篇文章主要介紹了
假币问题(二分法与三分法实现)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
#include <iostream>
#include <math.h>using namespace std;#define numnum 14
int coin[numnum] = {2,2,2,2,2,2,2,2,2,2,1,2,2,2};/*計算總重量 */
int Weight_Sum(int arr[], int low, int high)
{int sum = 0;for (int i = low; i <= high; i++)sum += arr[i];return sum;
}/* 二分法,找出假幣數組下標*/
int Weight_Coin2(int coin[], int coinNum, int low, int high)
{int mid = coinNum/2; //計算中值int r = coinNum % 2; //求余數,分別處理奇數偶數情況if (r == 0) //當硬幣剛好分為兩組時{int index = 0;int A, B;A = Weight_Sum(coin, low, low + mid - 1);B = Weight_Sum(coin, low + mid, high);if (coinNum == 2){if(A<B){index = low;}else{index = low+1;}return index;}else{if (A > B){index = Weight_Coin2(coin, mid, low + mid, high);return index;}else{if(A==B){return high;}index = Weight_Coin2(coin, mid, low, mid - 1);return index;}}}if (r == 1) //處理奇數情況{int index = high;int A, B;A = Weight_Sum(coin, low, low + mid - 1);B = Weight_Sum(coin, low + mid, high-1); //保證ab兩個組硬幣個數相同if (coinNum == 3) //當硬幣為三個分組時的處理{if(A==B){return high;}else if(A<B){return low;}else{return low+1;}}else{if (A == B) //當兩組硬幣的重量相等時{index = high;return index;}else if (A<B) //假幣在A組中的情況{index = Weight_Coin2(coin, mid, low, low+mid-1);return index;}else //假幣在b組中的情況{index = Weight_Coin2(coin, mid, mid, high-1);return index;}}}return 0;
}/* 三分法,找出假幣數組下標*/
int Weight_Coin(int coin[], int coinNum, int low, int high)
{int k = floor(coinNum / 3); //向下取整對硬幣進行分組int r = coinNum % 3; //求余數,目的是為了對其進行減治解決if (r == 0) //恰好分為三組的情況{int index = 0; //假幣的下標int A, B, C; //分別存儲三組硬幣的重量A = Weight_Sum(coin, low, low + k - 1); //劃分,數組下標從0開始B = Weight_Sum(coin, low + k, low + 2 * k - 1);C = Weight_Sum(coin, low + 2 * k, high);if (coinNum == 3) //當只剩下三個硬幣時{if (A == B) //如果前兩組硬幣的值相等,說明第三組是假幣,返回第三個硬幣的下標{index = high;}else if (A == C){index = high - 1;}else{index = low;}return index;}else //多于三個硬幣的情況{if (A == B) //假幣在第三組,處理方法和上面的相同{index = Weight_Coin(coin, k, low + 2 * k, high);return index;}else if (A == C){index = Weight_Coin(coin, k, low + k, low + 2 * k - 1);return index;}else{index = Weight_Coin(coin, k, low, k - 1);return index;}}}if (r == 1) //當分組的時候恰好多出一枚硬幣的情況處理{int index = high; //index的值為high,與上面的index=0的區別所在int A, B, C;A = Weight_Sum(coin, low, low + k - 1); //分別求三組硬幣的重量B = Weight_Sum(coin, low + k, low + 2 * k - 1);C = Weight_Sum(coin, low + 2 * k, high - 1); //劃分三組,多了一個硬幣,所以把最后一個硬幣單獨作為一組if (coinNum == 1) //當只剩下一個硬幣的時候,這個硬幣即為假幣,返回它的下標{return index;}else //硬幣個數多于一個時{if (A == B){if (A == C) //但三組硬幣的重量相等,則說明最后一枚硬幣為假幣,返回其下標return index;if ((A < C || A > C)) //另外的一種情況,假幣在c組中{index = Weight_Coin(coin, k, low + 2 * k, high - 1);return index;}}else if (A == C) //假幣在b組中{index = Weight_Coin(coin, k, low + k, low + 2 * k - 1);return index;}else //假幣在a組中{index = Weight_Coin(coin, k, low, k - 1);return index;}}}if (r == 2) //當恰好多出兩個硬幣的情況{int index = 0; //設置三個index,與上面的分別設置index為0和high的區別int index1 = high - 1;int index2 = high;int A, B, C;A = Weight_Sum(coin, low, low + k - 1);B = Weight_Sum(coin, low + k, low + 2 * k - 1);C = Weight_Sum(coin, low + 2 * k, high - 2); //劃分三組,多余的兩個硬幣另外考慮if (coinNum < 3) //當硬幣少于三個不能分組時的處理{int campare1; //參照物if (high != numnum - 1) //代碼核心所在,當硬幣不在分組中時campare1 = coin[numnum - 1]; //用最后一個數等于參照elsecampare1 = coin[0]; //用第一個數作為參照if (coin[high] == campare1) //如果最大的數等于參照,說明這個硬幣不是假幣index = low;if (coin[low] == campare1)index = high;return index;}else //當硬幣個數大于三個的情況{if (A == B && B == C) //當三組硬幣的重量相等時{int cam = coin[0]; //用第一個硬幣的重量作為參照物if (coin[high - 1] == cam) //如果倒數第二個硬幣的重量等于參照物,則返回最后一個硬幣的下標index = index2;if (coin[high] == cam)index = index1;return index;}else if ((A == B) && (A < C || A > C)) //假幣在c組中的情況{index = Weight_Coin(coin, k, low + 2 * k, high - 2);return index;}else if (A == C) //假幣在b組中的情況{index = Weight_Coin(coin, k, low + k, low + 2 * k - 1);return index;}else //假幣在a組中的情況{index = Weight_Coin(coin, k, low, k - 1);return index;}}}return 0;
}/*判斷假幣質量*/
void Judge(int number)
{int campareble;if (number != numnum - 1)campareble = coin[numnum - 1];elsecampareble = coin[0];if (coin[number] < campareble)cout << "假幣的位置為 " << number+1 << " 并且假幣偏輕" << endl;else if (coin[number] > campareble)cout << "假幣的位置為 " << number+1 << " 并且假幣偏重" << endl;elsecout << "參照出錯" << endl;
}int main()
{int number;number = Weight_Coin(coin, numnum, 0, numnum - 1);//Judge(number);cout<<number<<endl;number = Weight_Coin2(coin,numnum,0,numnum-1);cout<<number<<endl;return 0;
}
總結
以上是生活随笔為你收集整理的假币问题(二分法与三分法实现)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [译] 利用 Immutability(
- 下一篇: SHOWWINDOW最小化不好用