POJ1321棋盤問題


題目:

在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。

輸入:

輸入含有多組測試數據。 
每組數據的第一行是兩個正整數,n k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。 n <= 8 , k <= n 
當為-1 -1時表示輸入結束。 
隨后的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多余的空白行或者空白列)。 

輸出:

對於每一組數據,給出一行輸出,輸出擺放的方案數目C (數據保證C<2^31)。

樣例:

 

 

分析:及AC代碼如下

 

#include<iostream>
#include<sstream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
#include<functional>
#include<iomanip>
#include<numeric>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<cctype>
#define PI acos(-1.0)
const int INF = 0x3f3f3f;
const int NINF = -INF - 1;
typedef long long ll;
using namespace std;
int n, k, num;//記錄答案
int used[10];//記錄此列已經被使用
int judge[10][10];//記錄此格是否為棋盤區域
char c[10][10];//記錄棋盤
void func(int x, int y, int t)//t記錄當前已有幾個棋子
{
    if (t == k)
    {
        //cout << x << ' ' << y << ' ' << t << endl;
        num++;
        return;
    }
    for (int i = x + 1; i < n; ++i)//每次從下一行開始搜索
    {
        for (int j = 0; j < n; ++j)
        {
            if (judge[i][j] && !used[j])
            {
                //cout << i << ' ' << j << ' ' << t << endl;
                used[j] = 1;
                func(i, j, t + 1);
                used[j] = 0;//完成后復位
            }
        }
    }
}
int main()
{
    while (cin >> n >> k)
    {
        if (n == -1 && k == -1) break;
        num = 0;//初始化
        memset(used, 0, sizeof(used));
        memset(judge, 0, sizeof(judge));
        for (int i = 0; i < n; ++i)
        {
            for (int j = 0; j < n; ++j)
            {
                cin >> c[i][j];
                if (c[i][j] == '#') judge[i][j] = 1;//記錄該格為棋盤區域
            }
        }
        func(-1, 0, 0);//x=-1,第一次即從0開始(i=x+1)
        cout << num << endl;
    }
    return 0;
}

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM