题目链接: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 + 回溯)的更多相关文章

  1. POJ 1321 棋盘问题 --- DFS

    POJ 1321 题目大意:给定一棋盘,在其棋盘区域放置棋子,需保证每行每列都只有一颗棋子. (注意 .不可放 #可放) 解题思路:利用DFS,从第一行开始依次往下遍历,列是否已经放置棋子用一个数组标 ...

  2. POJ 1321 棋盘问题(DFS板子题,简单搜索练习)

    棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 44012   Accepted: 21375 Descriptio ...

  3. Poj 1321 棋盘问题 【回溯、类N皇后】

    id=1321" target="_blank">棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Subm ...

  4. (简单) POJ 1321 棋盘问题,回溯。

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

  5. POJ 1321 棋盘问题 dfs 难度:0

    http://poj.org/problem?id=1321 注意是在'#'的地方放棋子 矩阵大小不过8*8,即使是8!的时间复杂度也足以承受,可以直接dfs求解 dfs时标注当前点的行和列已被访问, ...

  6. POJ 1321 棋盘问题 DFS搜索

    简单搜索 练习一下回溯 #include <iostream> #include <cstdio> #include <cstring> #include < ...

  7. POJ 1321 棋盘问题 DFS 期末前水一水就好……

    A - 棋盘问题 Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Submit Sta ...

  8. POJ - 1321 棋盘问题 dfs分层搜索(n皇后变式)

    棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 47960   Accepted: 23210 Descriptio ...

  9. poj 1321 棋盘问题 (回溯法)

    棋盘问题 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 69951   Accepted: 33143 Descriptio ...

随机推荐

  1. bzoj3011 可并堆

    我们可以遍历得出每个节点到根节点的距离h,然后用可并堆进行维护.树形dp 我用的是pairing heap #include<cstdio> #include<algorithm&g ...

  2. [CF409F]000001

    题目大意:输入一个数,输出一个数(愚人节系列) 题解:$OEIS$的$A000001$(原来我不想写的,但是洛谷的智能推荐推荐我做这个...是不是我太菜了) 卡点:无 C++ Code: #inclu ...

  3. [Leetcode] n queens ii n皇后问题

    Follow up for N-Queens problem. Now, instead outputting board configurations, return the total numbe ...

  4. vector创建2维数组

    以前我要建立一个二维数组,总是使用 int N=5, M=6; vector<vector<int> > Matrix(N); for(int i =0; i< Matr ...

  5. spring中Constructor、@Autowired、@PostConstruct的顺序【转】

    其实从依赖注入的字面意思就可以知道,要将对象p注入到对象a,那么首先就必须得生成对象p与对象a,才能执行注入.所以,如果一个类A中有个成员变量p被@Autowired注解,那么@Autowired注入 ...

  6. 洛谷P1522 牛的旅行 Cow Tours

    ---恢复内容开始--- P1522 牛的旅行 Cow Tours189通过502提交题目提供者该用户不存在标签 图论 USACO难度 提高+/省选-提交该题 讨论 题解 记录 最新讨论 输出格式题目 ...

  7. springboot搭建web项目(转)

    转:http://blog.csdn.net/linzhiqiang0316/article/details/52589789 这几天一直在研究IDEA上面怎么搭建一个web-mvc的SpringBo ...

  8. 利用WebStorm来管理你的Github

    什么是Github Github是一个共享虚拟主机服务,用于存放使用Git版本控制的软件代码和内容项目,以最简单的方式来说,其实就是一个代码库,上面有全世界无数优秀的码农上传自己的作品和大家共享(当然 ...

  9. php SPL四种常用的数据结构

    1.栈[先进后出] $stack = new SplStack(); $stack->push('data1'); $stack->push('data2'); $stack->pu ...

  10. 搭建eova开发环境

    1.安装好maven 2.下载Eova项目解压到文件夹eova下 3.dos命令到eova文件夹下执行mvn eclipse:eclipse(注:构建eclipse项目命令) 4.修改*.tag文件错 ...