博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
POJ 1321 搜索
阅读量:4216 次
发布时间:2019-05-26

本文共 2327 字,大约阅读时间需要 7 分钟。

棋盘问题

Time Limit: 1000MS   Memory Limit: 10000K
Total Submissions: 60488   Accepted: 28974

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

类比八皇后,按照列放,但是区别与八皇后,这个不必每行都放,也就是可以跨行放,所以有 dfs(row+1,k)也就是对每行多出一种不放该行,直接跳到下一行的情况

刚开始,想通过在循环内对每行进行dfs依次到最后一行,但是这种思想不能涉及到,跨行的那些可能,所以错了

#include
#include
#include
#include
using namespace std;typedef long long LL;int n,k;char a[10][10];LL ans;bool vis[10];void dfs(int row,int k){ if(row > n || n-row < k) //剪枝 return ; if(k == 0){ ++ans; return; } for(int j = 0; j < n; ++j){ if(a[row][j] == '.') continue; if(!vis[j]){ vis[j] = true; dfs(row+1,k-1); vis[j] = false; } } dfs(row+1,k);}int main() { //freopen("C:Users/zhangwei/Desktop/input.txt","r",stdin); while(scanf("%d%d",&n,&k) ==2){ if(n == -1 && k == -1) break; ans = 0; for(int i = 0; i < n; ++i){ scanf("%s",a[i]); } memset(vis,false,sizeof(vis)); dfs(0,k); cout << ans << endl; } return 0; }

解法2:

#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;int n,k;const int N = 10;char a[N][N];LL tol;bool vis[N][N];bool book[N];bool judge(int x, int y){ for(int i = 0; i < n; ++i){ if(vis[x][i]) return false; } for(int i = 0; i < n; ++i){ if(vis[i][y]) return false; } return true;}void dfs(int x,int y,int k){ if(k < 0){ return ; } if(k == 0){ ++tol; return ; } if(x >= n){ return ; } if(a[x][y] == '#'){ if(!vis[x][y] && judge(x,y)){ vis[x][y] = true; dfs(x+1,0,k-1); vis[x][y] = false; } } // 这里 需要注意 不能加上else 也就是 总是执行的 (没有行尾 继续此行 否则就是该行没搜到 下一行继续搜索) if(y+1 < n) dfs(x,y+1,k); else dfs(x+1,0,k);}int main() { ios::sync_with_stdio(false); while(cin >> n >> k){ if(n == -1 && k == -1){ break; } tol = 0; memset(a,0,sizeof(a)); memset(vis,false,sizeof(vis)); memset(book,false,sizeof(book)); for(int i = 0; i < n; ++i){ cin >> a[i]; a[i][n] = '#'; } dfs(0,0,k); cout << tol <

 

转载地址:http://drimi.baihongyu.com/

你可能感兴趣的文章
Web前端学习笔记——AngularJS入门
查看>>
Web前端学习笔记——AngularJS之过滤器、服务、路由
查看>>
Web前端学习笔记——AngularJS之TodoMVC案例
查看>>
Web前端学习笔记——AngularJS之豆瓣电影案例
查看>>
Web前端学习笔记——模块化开发
查看>>
Web前端学习笔记——VueJS基础
查看>>
Web前端学习笔记——VueJS之过滤器、生命周期、请求、动画
查看>>
Web前端学习笔记——VueJS之组件、路由
查看>>
Web前端学习笔记——HTML基础
查看>>
Web前端学习笔记——CSS基础、选择器
查看>>
Web前端学习笔记——Webpack
查看>>
Web前端学习笔记——CSS样式、外观、复合选择器
查看>>
Web前端学习笔记——CSS显示模式、特性、背景
查看>>
Web前端学习笔记——CSS盒子模型、浮动
查看>>
Web前端学习笔记——CSS版心和布局流程、清除浮动
查看>>
Web前端学习笔记——CSS之Photoshop切图
查看>>
Web前端学习笔记——CSS定位、高级技巧、文字溢出、精灵图、Web字体
查看>>
Web前端学习笔记——CSS京东案例、BFC
查看>>
Web前端学习笔记——HTML5新标签与特性
查看>>
Web前端学习笔记——CSS3 新增选择器
查看>>