题目链接: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. 解析Mybaits的insert方法返回数字-2147482646的原因

    前言:前几天在做项目demo的时候,发现有一个很奇怪的现象,就是MyBatis发现更新和插入返回值一直为"-2147482646".无论怎么改,这个值一直不变...是在摸不着头脑, ...

  2. Codeforces Round #521 (Div. 3) F1. Pictures with Kittens (easy version)

    F1. Pictures with Kittens (easy version) 题目链接:https://codeforces.com/contest/1077/problem/F1 题意: 给出n ...

  3. POJ2492:A Bug's Life(种类并查集)

    A Bug's Life Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 45757   Accepted: 14757 题 ...

  4. Codeforces Round #520 (Div. 2) D. Fun with Integers

    D. Fun with Integers 题目链接:https://codeforc.es/contest/1062/problem/D 题意: 给定一个n,对于任意2<=|a|,|b|< ...

  5. 定时导出用户数据(expdp,impdp)

    一 定时导出数据: #!/bin/bash############################################################################### ...

  6. javascript简易下拉菜单效果

    JS代码: window.onload=function(){ var oDiv=document.getElementById('navMenu'); var aUl=oDiv.getElement ...

  7. jquery学习总计

    1,jquery的基础语法 $(selector).action(); 选择器(selector)查询和查找html元素,action()执行对函数的操作. 2.选择器 id,类,类型,属性,属性值等 ...

  8. 遍历文档内容,得到HTML层级结构

    嗯..没发现有写好的,那就自己写一个,刚好自己今天看了DOM操作的知识点,巩固一下. HTML可以表示为一个层次结构,生成的DOM Tree 就是类似与数据结构中的树一样,每个DOM节点都有它的chi ...

  9. Splunk笔记

    学习Splunk Fundamentals Part 2 (IOD) 和 Splunk Fundamentals Part 1课程的笔记. Chart Over By Tips: ….|chart c ...

  10. IPC网络高清摄像机基础知识4(Sensor信号输出YUV、RGB、RAW DATA、JPEG 4种方式区别) 【转】

    转自:http://blog.csdn.net/times_poem/article/details/51682785 [-] 一 概念介绍 二 两个疑问 三 RAW和JPEG的区别 1 概念说明 3 ...