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 ...
随机推荐
- Netscaler GSLB的主备数据中心解决方案
Netscaler GSLB的主备数据中心解决方案 http://blog.51cto.com/caojin/1898182 GSLB的主.备数据中心解决方案思路: 其实这只是多数据中心的一个特例而已 ...
- BZOJ1513 [POI2006]Tet-Tetris 3D 【二维线段树】
题目链接 BZOJ1513 题解 真正地理解了一波线段树标记永久化的姿势 每个节点维护两个值\(v\)和\(tag\) \(v\)代表儿子中的最值 \(tag\)代表未下传的最值 显然节点的区间大于等 ...
- 【BZOJ 4556】[Tjoi2016&Heoi2016]字符串 SAM+二分+主席树
这道题市面上就两种法:一种是SA+二分+主席树,一种是SAM+二分+主席树(有不少人打线段树合并???)(除此之外还有一种利用炒鸡水的数据的暴力SA,贼快.....)(当时学SA的时候没做这道题,现在 ...
- 适用于iview的表格转Excel插件
在网上找的一个表格转excel插件,经过修改后使其适用于iview中的table组件 let idTmr; const getExplorer = () => { let explorer = ...
- ubuntu下opencv使用cvNamedWindow()和cvShowImage()出错的解决方法
重装系统和opencv,编译运行显示一副图像的程序,报错如下 liurf@liurf-Lenovo-G470:~/WorkSpace/slambook-master/ch5/imageBasics$ ...
- Java之戳中痛点 - (1)易变业务使用脚本语言编写
脚本语言的3大特征: 1.灵活:脚本语言一般是动态类型,可以不声明变量类型直接使用,也可以在运行期改变类型:2.便捷:脚本语言是解释性语言,在运行期变更非常方便,而不用重启服务3.简单:脚本语言语法比 ...
- [Book Content]Python进阶
python进阶 原书内容https://github.com/eastlakeside/interpy-zh 通过记录书本目录和大概内容做一个记录,方便以后回顾检索. Chapter Title B ...
- linux网络编程系列-TCP/IP模型
### OSI:open system interconnection ### 开放系统互联网模型是由ISO国际标准化组织定义的网络分层模型,共七层 1. 物理层:物理定义了所有电子及物理设备的规范, ...
- MUI -- plus初始化原理及plus is not defined,mui is not defined 错误汇总
不要在没有plus和mui的环境下调用相关API 普通浏览器里没有plus环境,只有HBuilder真机运行和打包后才能运行plus api. 在普通浏览器里运行时plus api时控制台必然会输出p ...
- idea 将工程项目打包成war
1.File--Project structure ---- Artifacts ----- + -----web Application :Archive ---for ' **:war explo ...