1. 程式人生 > 其它 >GDUT-21級排位賽第一場 - G. Board Game(暴力搜尋)

GDUT-21級排位賽第一場 - G. Board Game(暴力搜尋)

題意

Feras bought to his nephew Saleem a new game to help him learning calculating. The game consists of a board with 4 rows and 4 columns with 16 cubes. Every cube has a number from 1 to 16. Let's define the power of a column as the sum of its elements. In the same way, the power of a row is the sum of its elements. Saleem should arrange the cubes in the board such that the power of all columns and all rows are equal. To make the game easier, the nice uncle, Feras, will help him arranging 7 cubes, and Saleem should arrange the rest of the cubes.

輸入格式

Your program will be tested on one or more test cases. The first line of the input will be a single integer T, the number of test cases (1 ≤  T ≤  100). Then the test cases. Each test case has four lines containing four integers. The j-th number in the i-th line describes the cell (i,j) of the board. If the number is -1 then the cell is empty and you have to fill it, otherwise, uncle Feras has already filled this cell.

輸出格式

For each test case print a line in the following format: "Case c:" where c is the test case number starting from 1 then print the board in four lines every line has four numbers separated by space. If there is more than one solution print the solution that has the smallest order (See the notes below).

樣例1

Input Output
1
-1 -1 -1 -1
-1 -1 -1 -1
-1 5 13 12
3 8 9 14
Case 1:
11 6 10 7
16 15 2 1
4 5 13 12
3 8 9 14

思路

深搜。

每次搜到填完的時候判斷一下符不符合條件,具體做法也很簡單,就是開個陣列t[8]分別記錄4行和4列的數的和是否相等。

程式碼

#include <bits/stdc++.h>
using namespace std;
const int N = 9;
int a[N][N];
int vis[20];

bool is_ok() {
    int t[8] = {0};
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 4; j++) {
            t[i] += a[i][j];
            t[j+4] += a[i][j];
        }
    }
    for (int i = 1; i < 8; i++) {
        if (t[i] != t[i-1]) return 0;
    }
    return 1;
}

bool dfs(int step) {
    if (step == 16) {
        if (is_ok()) return 1;
        return 0;
    } else {
        if (a[step/4][step%4] == -1) {
            for (int i = 1; i <= 16; i++) {
                if (!vis[i]) {
                    vis[i] = 1;
                    a[step/4][step%4] = i;
                    if (dfs(step+1)) return 1;
                    vis[i] = 0;
                    a[step/4][step%4] = -1;
                }
            }
        } else if (dfs(step+1)) return 1;
        return 0;
    }
}

int main() {
    int t;
    cin >> t;
    int kase = 1;
    while (t--) {
        memset(vis,0,sizeof vis);
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                cin >> a[i][j];
                if (a[i][j] != -1) vis[a[i][j]] = 1;
            }
        }
        dfs(0);
        printf("Case %d:\n", kase++);
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (j == 0) printf("%d", a[i][j]);
                else printf(" %d", a[i][j]);
            }
            puts("");
        }
    }
}