POJ 1321 棋盘问题(DFS)

题目链接

题意:在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别。要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子的所有可行的摆放方案C。

分析:dfs水题。

争取从今天开始用多用java吧

JAVA

import java.util.*;
//import java.math.BigInteger;

public class Main{
	
	
	public static int n;
	public static int k;
	public static int ans;
	public static int vis[]=new int [10];
	public static char a[][]=new char [10][10];
	public static void dfs(int row, int step) {
		
		if (step==k) {
			ans++;
			return;
		}
		
		for (int i=row; i<n; i++) {
			for (int j=0; j<n; j++) {
				if (a[i][j]=='#' && vis[j]==0) {
					vis[j]++;
					dfs(i+1,step+1);
					vis[j]--;
				}
			}
		}
		return ;
	}
	
	public static void main(String[] args) {

		Scanner cin =new Scanner (System.in);
		while (cin.hasNext()) {				
			ans=0;
			n=cin.nextInt();
			k=cin.nextInt();
			if (n==-1 && k==-1) break;
			for (int i=0; i<n; i++) {
				vis[i]=0;
				for (int j=0; j<n; j++) {
					a[i][j]='\0';
				}
			}			
			for (int i=0; i<n; i++) {			
				String t=cin.next();
				for (int j=0; j<n; j++) {				
					a[i][j]=t.charAt(j);
				}
			}			
			dfs(0,0);
			System.out.println(ans);
		}	
		cin.close();
	}
}

C++

#include <iostream>
#include <cstring>

using namespace std;
int n,k;
int ans=0;
char a[10][10];
int vis[10];
void dfs(int row, int step){
	
	if (step==k){
		ans++;
		return;
	}
	for (int i=row; i<n; i++){
		for (int j=0; j<n; j++){
			if (a[i][j]=='#' && !vis[j]){
				vis[j]++;
				dfs(i+1,step+1);
				vis[j]--;
			}
		}
	}
	return;
}

int main(){
	
	
	while (cin>>n>>k){
		if (n==-1 && k==-1) break;
		ans=0;
		memset(a,'\0',sizeof(a));
		memset(vis,0,sizeof(vis));
		
		for (int i=0; i<n; i++){
			for (int j=0; j<n; j++){
				cin>>a[i][j];
			}
		}
		dfs(0,0);
		cout<<ans<<endl;	
	}
}

POJ 1321 排兵布阵问题可以使用 DFS 算法求解。 题目要求在一个 n x n 的棋盘上,放置 k 个棋子,其中每行、每列都最多只能有一个棋子。我们可以使用 DFS 枚举每个棋子的位置,对于每个棋子,尝试将其放置在每一行中未被占用的位置上,直到放置了 k 个棋子。在 DFS 的过程中,需要记录每行和每列是否已经有棋子,以便在尝试放置下一个棋子时进行判断。 以下是基本的 DFS 模板代码: ```python def dfs(row, cnt): global ans if cnt == k: ans += 1 return for i in range(row, n): for j in range(n): if row_used[i] or col_used[j] or board[i][j] == '.': continue row_used[i] = col_used[j] = True dfs(i + 1, cnt + 1) row_used[i] = col_used[j] = False n, k = map(int, input().split()) board = [input() for _ in range(n)] row_used = [False] * n col_used = [False] * n ans = 0 dfs(0, 0) print(ans) ``` 其中,row 代表当前尝试放置棋子的行数,cnt 代表已经放置的棋子数量。row_used 和 col_used 分别表示每行和每列是否已经有棋子,board 则表示棋盘的状态。在尝试放置棋子时,需要排除掉无法放置的位置,即已经有棋子的行和列,以及棋盘上标记为 '.' 的位置。当放置了 k 个棋子时,即可计数一次方案数。注意,在回溯时需要将之前标记为已使用的行和列重新标记为未使用。 需要注意的是,在 Python 中,递归深度的默认限制为 1000,可能无法通过本题。可以通过以下代码来解除限制: ```python import sys sys.setrecursionlimit(100000) ``` 完整代码如下:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值