五個整數任意組合(加減)得到1~122之間的數
阿新 • • 發佈:2018-12-31
//問題描述
/*
給定五個整數1,3,9,27,81,這個五個整數可以任意組合進行加減(可以是五個數中的部分相加),這五個數組合進行加減可以得到1~122之間的數, 任意輸入1~122之間的一個整數,得到其相應的組合,並且按照由大到小的順序輸出其表示式
示例輸入輸出
輸入:5
輸出:9-3-1
*/
之前寫過一個華為上機題,五個數字相加任意組合成1~122之間的數,這幾天看到了,感覺當時寫的方法太挫了,居然是利用多層迴圈,那如果有更多數,或者數字個數不確定,那不就沒轍了。
對於這個數字任意組合,很容易想到的就是排列組合(輸出n個數字的所有排列)。類似,就可以用回溯的方法來實現。這裡回溯其實也就是直接搜尋,執行過程與利用多層迴圈實質相同,但對於解決問題比多層迴圈的挫辦法要實用得多。
程式碼與求n個數字的排列類似,也是到達最裡面一層判斷是否滿足條件,否則返回上一層,並更改這一層的狀態,繼續往下一層走。
#include <iostream> using namespace std; int weights[5] = {81,27,9,3,1}; void combine(int n, int sign[], int value) { if (n == 5) { int sum = 0; for (int i = 0; i < 5; i++) { int tmp = weights[i]*sign[i]; sum += tmp; } if (sum == value) { //輸出 bool flag = false; for (int j = 0; j < 5; j++) { if (sign[j] != 0) { if (sign[j] == 1) { if (flag) { cout << "+"; } cout << weights[j]; } else if (sign[j] == -1) { cout << "-" << weights[j]; } flag = true; } } cout << endl; } } else { sign[n] = 0; combine(n+1, sign, value); sign[n] = 1; combine(n+1, sign, value); sign[n] = -1; combine(n+1, sign, value); } } int main() { int Value; int sign[5]; while(cin>>Value) { combine(0, sign, Value); } return 0; }