题目描述
在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。
输入
输入含有多组测试数据。
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n
当为-1 -1时表示输入结束。
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。
输出
对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。
样例:
输入: 输出:
2 1 2 #. 1 .# 4 4 ...# ..#. .#.. #... -1 -1
思路:由于要不同行不同列,那就从第一行开始每行dfs,并在这一轮dfs找到有位置的列时,先标记一下该列,表示到过该位置,退出这轮dfs再重新归0刷新
package com.company;
import java.io.*;
import java.util.*;
import java.math.*;
public class Main {
public static void main(String[] args) {
InputStream inputStream = System.in;
OutputStream outputStream = System.out;
InputReader in = new InputReader(inputStream);
PrintWriter out = new PrintWriter(outputStream);
TaskA solver = new TaskA();
solver.solve(1, in, out);
out.close();
}
static class TaskA {
//定义全局变量
int sum=0,n=0;//sum为方案数
char map[][]=new char[10][10];//图
int vis[]=new int[100];//标记该方案该列位置棋子能否落下
public void solve(int testNumber, InputReader in, PrintWriter out) {
while (in.hasNext()){
sum=0;
n=in.nextInt();
int k=in.nextInt();
if(n==-1){
break;
}
for (int i = 0; i <n ; i++) {
String s=in.next();
for (int j = 0; j <n ; j++) {
char x=s.charAt(j);
map[i][j]=x;
}
}
dfs(0,k);
out.println(sum);
}
}
void dfs(int m,int k){//m为行位置,k为剩余棋子数量
if(k==0){
//k=0表示棋下完了,这轮dfs结束方案可行+1
sum++;
return;
}
for (int i = m; i <n ; i++) {
for (int j = 0; j < n; j++) {
if(map[i][j]=='.'||vis[j]==1){//判断能否在这里落棋,vis[j]为1表示在这轮dfs中,这个位置已经到过了
continue;
}
vis[j]=1;//标记该列位置,且已经落下一枚棋子了
dfs(i+1,k-1);//因为棋子要不同行所以一找完位置就从下一行开始搜,棋子数量也减1,
vis[j]=0;//该轮dfs结束,重新标为0,表示没来过
}
}
}
}
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
boolean hasNext()
{
while (tokenizer == null || !tokenizer.hasMoreTokens())
{
try
{
tokenizer = new StringTokenizer(reader.readLine());
} catch (Exception e)
{
return false;
// TODO: handle exception
}
}
return true;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public String nextLine()
{
String str = null;
try
{
str = reader.readLine();
} catch (IOException e)
{
e.printStackTrace();
}
return str;
}
public int nextInt() {
return Integer.parseInt(next());
}
public double nextDouble(){
return Double.parseDouble(next());
}
public long nextLong(){
return Long.parseLong(next());
}
public BigInteger nextBigInteger()
{
return new BigInteger(next());
}
public BigDecimal nextBigDecimal()
{
return new BigDecimal(next());
}
}
}