原題
棋盤問題
Description
在一個給定形狀的棋盤(形狀可能是不規則的)上面擺放棋子,棋子沒有區別。要求擺放時任意的兩個棋子不能放在棋盤中的同一行或者同一列,請編程求解對於給定形狀和大小的棋盤,擺放k個棋子的所有可行的擺放方案C。Input
輸入含有多組測試數據。每組數據的第一行是兩個正整數n和k,用一個空格隔開,表示了將在一個n*n的矩陣內描述棋盤,以及擺放棋子的數目。(n<=8,k<=n)
當n和k均爲-1時表示輸入結束。
隨後的n行描述了棋盤的形狀:每行有n個字符,其中 # 表示棋盤區域, . 表示空白區域(數據保證不出現多餘的空白行或者空白列)。
Output
對於每一組數據,給出一行輸出,輸出擺放的方案數目C(數據保證C<2^31)。Sample Input
2 1#.
.#
4 4
...#
..#.
.#..
#...
-1 -1
Sample Output
21
涉及知識及算法
然後就從下一行開始尋找可行的地方,直到我們擺放的棋子數與我們被要求擺放的棋子數相同時,我們就將方案數進行一次++,然後在進行遞歸下去。
代碼
#include <cstdio>
#include <cstdlib>
#include <iostream>
#include <cstring>
using namespace std;
int n,k,ans;
//棋盤
char Map[12][12];
int vis[12];
int DFS(int i,int cur)
{
//如果可以擺完k個棋子,方案數加一併返回
if(cur>=k)
{
ans++;
return 0;
}
//從當前行開始,並在其中循環遍歷以實現所有
// 可能情況的組合·
for(int x=i;x<n;x++)
{
for(int y=0;y<n;y++)
{
if(!vis[y]&&Map[x][y]=='#')
{
vis[y]=1;
//在下一列擺放下一個
DFS(x+1,cur+1);
//一個方案模擬後就還原
vis[y]=0;
}
}
}
return 0;
}
int main()
{
//freopen("in.txt","r",stdin);
while(scanf("%d%d",&n,&k)&&n!=-1)
{
ans=0;
memset(Map,0,sizeof(Map));
memset(vis,0,sizeof(vis));
for(int i=0;i<n;i++)
{
scanf("%s",Map[i]);
}
DFS(0,0);
printf("%d\n",ans);
}
return 0;
}
/**************************************************************
Problem: 1310
Language: C++
Result: Accepted
Time:0 ms
Memory:1504 kb
****************************************************************/
文章轉載自博客園博主心向晴,鏈接http://www.cnblogs.com/xinxiangqing/p/4692994.html,向他/她表示感謝