棋盘问题
Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 60815   Accepted: 29135

Description

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

Input

输入含有多组测试数据。 
每组数据的第一行是两个正整数,n k,用一个空格隔开,表示了将在一个n*n的矩阵内描述棋盘,以及摆放棋子的数目。 n <= 8 , k <= n 
当为-1 -1时表示输入结束。 
随后的n行描述了棋盘的形状:每行有n个字符,其中 # 表示棋盘区域, . 表示空白区域(数据保证不出现多余的空白行或者空白列)。 

Output

对于每一组数据,给出一行输出,输出摆放的方案数目C (数据保证C<2^31)。

Sample Input

2 1
#.
.#
4 4
...#
..#.
.#..
#...
-1 -1

Sample Output

2
1

思路:典型回溯水题,不过这一次学到了不存小地图方法,就是每次存棋盘的位置就行了。而且这个样子的话,相当于给每个位置标好了号码,这样就可以吧问题转变成组合问题,我们拿个栗子说明

输入样例:

#..
.#.
..#
- - 输出样例:

很明显的1,2,3,然后从中选两个,方式就是1先找后面能满足条件的,有1和2、1和3;然后从2往后找,有2和3;然后从3往后找,结束。

注意:提交的时候WA了,试试换个提交方式!!!随便放一段毒代码

#include <iostream>
#include <cstdio>
#include <string>
#include <string.h>
#define ll long long
using namespace std; int pa[], pb[]; //棋盘摆放 #棋盘区域 .空白区域
int n, k; //表明是n*n的矩阵 摆放k个棋子
int vx[] = { }; //走过的行的位置
int vy[] = { }; //走过的列的位置
ll sum = ; //摆放的方法
int ss; //记录#的个数
int visit[] = { }; //走过的点 void dfs(int i, int j){
if (j == k){
sum++;
}
else{
for (int l = i; l<ss; ++l){
if (visit[l] == && vx[pa[l]] == && vy[pb[l]] == ){
vx[pa[l]] = ;
vy[pb[l]] = ;
visit[l] = ;
dfs(l + , j + );
vx[pa[l]] = ;
vy[pb[l]] = ;
visit[l] = ;
}
}
}
} int main()
{
ios::sync_with_stdio(false);
while (~scanf("%d%d",&n,&k)) {
getchar();
if (n == - && k == -)break;
sum = ;
ss = ;
memset(vx, , sizeof(vx));
memset(vy, , sizeof(vy));
memset(visit, , sizeof(visit)); for (int i = ; i<n; ++i){
for (int j = ; j<n; ++j){
char temp;
cin >> temp;
if (temp == '#'){
pa[ss] = i; //把棋盘区域(i,j)加进数组
pb[ss++] = j;
}
}
}
dfs(, ); //从第一个为#的点开始,一开始摆放的棋子数为0;
cout << sum << endl;
}
return ;
}

C++提交AC,G++WA

以下AC代码:

#include<iostream>
#include<string.h>
using namespace std;
int n, k, sum, len;
int pa[], pb[], vx[] = { }, vy[] = { }, vis[] = { };
void dfs(int s, int c)
{
if (c > k)return;
if (c == k)sum++;
else {
for (int i = s; i < len;i++)
if (vis[i] == && vx[pa[i]] == && vy[pb[i]] == ){
vis[i] = vx[pa[i]] = vy[pb[i]] = ;
dfs(i + , c + );
vis[i] = vx[pa[i]] = vy[pb[i]] = ;
}
}
}
int main()
{
ios::sync_with_stdio(false);
while (cin >> n >> k, n != - && k != -){
len = sum = ; for (int i = ; i < n;i++)
for (int j = ; j < n; j++){
char ch; cin >> ch;
if (ch == '#'){
pa[len] = i;
pb[len++] = j;
}
}
dfs(, );
cout << sum << endl;
}
return ;
}

POJ -棋盘问题的更多相关文章

  1. poj棋盘分割(记忆化)

    http://poj.org/problem?id=1191 黑书上P116 想了挺久 没想出来 想推出一公式来着 退不出来.. 想偏了  正解:递归 #include <iostream> ...

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

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

  3. OpenJudge/Poj 1321 棋盘问题

    1.链接地址: http://bailian.openjudge.cn/practice/1321 http://poj.org/problem?id=1321 2.题目: 棋盘问题 Time Lim ...

  4. OpenJudge/Poj 1191 棋盘分割

    1.链接地址: http://bailian.openjudge.cn/practice/1191/ http://poj.org/problem?id=1191 2.题目: 总时间限制: 1000m ...

  5. HDU 2517 / POJ 1191 棋盘分割 区间DP / 记忆化搜索

    题目链接: 黑书 P116 HDU 2157 棋盘分割 POJ 1191 棋盘分割 分析:  枚举所有可能的切割方法. 但如果用递归的方法要加上记忆搜索, 不能会超时... 代码: #include& ...

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

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

  7. POJ 1321 - 棋盘问题 - [经典DFS]

    题目链接:http://poj.org/problem?id=1321 Time Limit: 1000MS Memory Limit: 10000K Description 在一个给定形状的棋盘(形 ...

  8. poj - 1191 - 棋盘切割(dp)

    题意:将一个8*8的棋盘(每一个单元正方形有个分值)沿直线(竖或横)割掉一块,留下一块,对留下的这块继续这样操作,总共进行n - 1次,得到n块(1 < n < 15)矩形,每一个矩形的分 ...

  9. POJ - 1191 棋盘分割 记忆递归 搜索dp+数学

    http://poj.org/problem?id=1191 题意:中文题. 题解: 1.关于切割的模拟,用递归 有这样的递归方程(dp方程):f(n,棋盘)=f(n-1,待割的棋盘)+f(1,割下的 ...

随机推荐

  1. 3-1 vue生存指南 - todolist实现-数据渲染

    由于Vue.js作者是中国人,会说汉语,所以国内生态会更好一点.Vue.js作者是尤雨溪,

  2. Python机器学习算法 — 决策树(Decision Tree)

    决策树 -- 简介         决策树(decision tree)一般都是自上而下的来生成的.每个决策或事件(即自然状态)都可能引出两个或多个事件,导致不同的结果,把这种决策分支画成图形很像一棵 ...

  3. bzoj 1828: [Usaco2010 Mar]balloc 农场分配【贪心+线段树】

    长得挺唬人的贪心,按照右端点排序,用最小值线段树的询问判断当前牛是否能放进去,能的话更新线段树,ans++ 来自https://www.cnblogs.com/rausen/p/4529245.htm ...

  4. P3573 [POI2014]RAJ-Rally

    传送门 很妙的思路 首先这是一个DAG,于是我们先在原图和反图上各做一遍,分别求出\(diss_i\)和\(dist_i\)表示从\(i\)点出发的最短路和以\(i\)为终点的最短路 我们考虑把点分为 ...

  5. [转]微信开发.Net 接入示例

    本文转自:http://my.oschina.net/lcak/blog/219618 微信公众平台接口开发官方仅提供了 PHP 接入示例代码, 网上找到的.Net代码多半需要积分下载, 所以自己写了 ...

  6. Android开发: 关于性能需要考虑的

    刚做Android开发时,只管完成任务,将需求完成,以能完成一款界面酷炫的app为自豪.然而,随着代码量的增加,越来越意识到,一款成功的移动端产品,光有酷炫的外衣还不够,还需要在各方面都优秀. 试想, ...

  7. form表单清空、重置

    form_live为formID <input type="button" value="重置" onclick="$('#form_live' ...

  8. C++ 模板template和template

    原文链接:https://blog.csdn.net/skyleung/article/details/42195509 template<class T>和template<typ ...

  9. 6.15 分解IP地址

    问题:将一个IP地址字段分解到列中,考虑下面列出的IP地址: 111.22.3.4 要得到如下所示的查询结果: +-----+----+---+---+| a   | b  | c | d |+--- ...

  10. 梦想CAD控件安卓文字样式

    增加文字样式 用户可以增加文字样式到数据库,并设置其字体等属性,具体实现代码如下: // 增加文字样式 //getCurrentDatabase()返回当前数据库对象 //getTextstyle() ...