挑戰程序設計競賽 2章習題 POJ 3187 Backward Digit Sums DFS

地址 https://vjudge.net/problem/POJ-3187

題意是給你一個N(1<=N<=10)

要求將1到N的數字進行排列 然後進行楊輝三角運算

每行的數字等於上一行相同座標和上一行相同座標右邊的兩個數字之和

最後得到唯一的一個數字

現在給予N 和一個M

請問初始的N個數字該如何排列才能得到這個M
輸入
n m
n爲數字個數 m爲要求的最後的楊輝三角的和

輸出
一行數字使用空格隔開
爲初始的N個數字的排列 如果有多個答案 輸出字典序最小的一個
樣例
Sample Input
4 16
Sample Output
3 1 2 4  (3 2 1 4 也是答案 但是它不是字典序最小的排列)

 

解答

首先按照字典序DFS排列 N個數字,然後得到該排列最後的楊輝三角的頂端的數字 與輸入的m比對,尋找答案

也可以使用楊輝三角的公式直接計算出最後的和 與m進行比較,這裏採取的是暴力模擬計算楊輝三角的頂端數字

#include <iostream>

using namespace std;
/*
Sample Input
4 16
Sample Output
3 1 2 4
*/

const int N = 15;

int arr[N];
int used[N];
int n, m;

int check[N][N];

//暴力模擬楊輝三角的記錄
bool CheckArr() {
    for (int i = 0; i < n; i++) {
        check[0][i] = arr[i];
    }

    for (int i = 1; i < n; i++) {
        for (int j = 0; j < n - i; j++) {
            check[i][j] = check[i - 1][j] + check[i - 1][j + 1];
        }
    }

    if (check[n - 1][0] == m) return true;
    return false;
}

bool dfs(int idx)
{
    if (idx >= n) {
        if (CheckArr() == true) {
            for (int i = 0; i < n; i++) {
                cout << arr[i] << " ";
            }
            cout << endl;
            return true;
        }
        return false;
    }

    for (int i = 1; i <= n; i++) {
        if (used[i] == 0) {
            used[i] = 1; arr[idx] = i;
            if (true == dfs(idx + 1)) return true;
            used[i] = 0;
        }
    }
    return false;
}


int main()
{
    cin >> n >> m;
    dfs(0);
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章