POJ 1321 棋盘问题 (DFS + 回溯)
题目链接:http://poj.org/problem?id=1321
题意:中文题目,就不多说了。。。。。。
思路:
解题方法挺多,刚开始想的是先从N行中选择出来含有“#”的K行,再在这K行中放置K个棋子,就好了。时间复杂度为O( C(n, k) * k! ),真实写的时候其实用了2N * k!,勉强也过了。后面又想到可以先从第一个出现的“#”开始搜,搜完之后直接跳到下一行继续,就不用第一次做那么麻烦了。
代码:
(1)
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <string> typedef long long LL;
using namespace std;
const int MAXN = ;
int map[MAXN + ][MAXN + ];
int row[MAXN + ];
int chose[MAXN + ];
int n, k;
int ans; void chessDFS(int t) {
if(t > k) {
++ans;
}
else {
int cnt = ;
for(int i = ; i <= n; i++) {//从1 ~ n 行找到放置第t个棋子所在的行。
if(chose[i]) ++cnt;
if(cnt == t && chose[i]) {
for(int j = ; j <= n; j++) {//在该行寻找“#”
if(map[i][j] == '#' && row[j] == ) {
chose[i] = j; // 第t个棋子放在第 i行的第j个位置
row[j] = ;
chessDFS(t + );
row[j] = ;
}
}
}
}
}
} int check(int k) {
for(int i = ; i <= n; i++) {
if(map[k][i] == '#' && chose[k]) return ;
}
return ;
} void LineDFS(int t){
if(t > n){
int cnt = ;
for(int i = ; i <= n; i++) {
if(check(i)) cnt++;//判断chose数组中 1 的个数, 同时判断被选中行是否含有“#”,同时满足才算正真的选中
}
if(cnt == k) {//说明有K行被选中,且符合条件
memset(row, , sizeof(row));
chessDFS();//在这已经被选中的K行中放置K个棋子
}
}
else {
for(int i = ; i < ; i++) {//每行有两种状态,选和不选
chose[t] = i; //chose[t] = 1代表第t行被选则
LineDFS(t + );
}
}
} int main() {
while(scanf("%d%d", &n, &k) == && (n != - && k != -)) {
memset(map, '!', sizeof(map));
memset(row, , sizeof(row));
for(int i = ; i <= n; i++) {
getchar();
for(int j = ; j <= n; j++) {
map[i][j] = getchar();
}
}
ans = ;
LineDFS();//从N行中选择出来K行
printf("%d\n", ans);
}
return ;
}
(2)
#include <iostream>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <stack>
#include <queue>
#include <vector>
#include <algorithm>
#include <string> typedef long long LL;
using namespace std;
const int MAXN = ;
int map[MAXN + ][MAXN + ];
int row[MAXN + ];
int chose[MAXN + ];
int n, k;
int ans; void DFS(int t, int line) {
for(int i = ; i <= n; i++) {
if(map[line][i] == '#' && !row[i]) {
row[i] = ;
if(t == k) ++ans;
else {
for(int j = line + ; j <= n - (k - t) + ; j++) {//第t+1个点从line+1行开始放
DFS(t + , j);
}
}
row[i] = ;
}
}
} int main() {
//freopen("input", "r", stdin);
//freopen("output", "w", stdout);
while(scanf("%d%d", &n, &k) == && (n != - && k != -)) {
memset(map, '!', sizeof(map));
memset(row, , sizeof(row));
for(int i = ; i <= n; i++) {
getchar();
for(int j = ; j <= n; j++) {
map[i][j] = getchar();
}
}
ans = ;
for(int i = ; i <= n - k + ; i++) DFS(, i);//第一个点从第一行开始放
printf("%d\n", ans);
}
return ;
}
POJ 1321 棋盘问题 (DFS + 回溯)的更多相关文章
- POJ 1321 棋盘问题 --- DFS
POJ 1321 题目大意:给定一棋盘,在其棋盘区域放置棋子,需保证每行每列都只有一颗棋子. (注意 .不可放 #可放) 解题思路:利用DFS,从第一行开始依次往下遍历,列是否已经放置棋子用一个数组标 ...
- POJ 1321 棋盘问题(DFS板子题,简单搜索练习)
棋盘问题 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 44012 Accepted: 21375 Descriptio ...
- Poj 1321 棋盘问题 【回溯、类N皇后】
id=1321" target="_blank">棋盘问题 Time Limit: 1000MS Memory Limit: 10000K Total Subm ...
- (简单) POJ 1321 棋盘问题,回溯。
Description 在一个给定形状的棋盘(形状可能是不规则的)上面摆放棋子,棋子没有区别.要求摆放时任意的两个棋子不能放在棋盘中的同一行或者同一列,请编程求解对于给定形状和大小的棋盘,摆放k个棋子 ...
- POJ 1321 棋盘问题 dfs 难度:0
http://poj.org/problem?id=1321 注意是在'#'的地方放棋子 矩阵大小不过8*8,即使是8!的时间复杂度也足以承受,可以直接dfs求解 dfs时标注当前点的行和列已被访问, ...
- POJ 1321 棋盘问题 DFS搜索
简单搜索 练习一下回溯 #include <iostream> #include <cstdio> #include <cstring> #include < ...
- POJ 1321 棋盘问题 DFS 期末前水一水就好……
A - 棋盘问题 Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u Submit Sta ...
- POJ - 1321 棋盘问题 dfs分层搜索(n皇后变式)
棋盘问题 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 47960 Accepted: 23210 Descriptio ...
- poj 1321 棋盘问题 (回溯法)
棋盘问题 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 69951 Accepted: 33143 Descriptio ...
随机推荐
- vb常用函数一览表
常用内部函数 数学函数 函数 功能 示例 结果 说明 Abs(x) 绝对值 Abs(-50.3) 50.3 Exp(x) 自然指数 Exp(2) e^2 e(自然对数的底)的某次方 Fix(x) ...
- [IOI2000][POJ1160]Post office
题面在这里 题意 一条路上有\(n\)个村庄,坐标分别为\(x[i]\),你需要在村庄上建设\(m\)个邮局,使得 每个村庄和最近的邮局之间的所有距离总和最小,求这个最小值. 数据范围 \(1\le ...
- [Leetcode] Longest consecutive sequence 最长连续序列
Given an unsorted array of integers, find the length of the longest consecutive elements sequence. F ...
- 洛谷 P2486 [SDOI2011]染色/bzoj 2243: [SDOI2011]染色 解题报告
[SDOI2011]染色 题目描述 给定一棵有n个节点的无根树和m个操作,操作有2类: 1.将节点a到节点b路径上所有点都染成颜色c: 2.询问节点a到节点b路径上的颜色段数量(连续相同颜色被认为是同 ...
- SCU3037 Painting the Balls
Description Petya puts the \(N\) white balls in a line and now he wants to paint some of them in bla ...
- Vim使用小记(二)插件管理
By francis_hao Mar 8,2017 Vundle Vundle,全称为Vim bundle,是一个插件管理器.可以对vim插件进行安装和卸载. Vundle的安装方法看这里[参考 ...
- bzoj 4237 稻草人 CDQ
稻草人 Time Limit: 40 Sec Memory Limit: 256 MBSubmit: 1433 Solved: 626[Submit][Status][Discuss] Descr ...
- 两数之和 [ leetcode ]
原题地址:https://leetcode-cn.com/articles/two-sum/ 给定一个整数数组和一个目标值,找出数组中和为目标值的两个数. 你可以假设每个输入只对应一种答案,且同样的元 ...
- JAX-WS 注解
一.概述 “基于 XML 的 Web Service 的 Java API”(JAX-WS)通过使用注释来指定与 Web Service 实现相关联的元数据以及简化 Web Service 的开发.注 ...
- win7---虚拟wifi无法启动承载网络
转载自:http://nbbbs.zol.com.cn/40/32108_397955.html 解决方案:控制面板→硬件和声音→电源选项→更改计划设置→更改高级电源设置→无线适配器设置→节能模式,改 ...