POJ-1321-棋盘问题
2016-03-09 13:30
239 查看
K - 棋盘问题
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
Submit
Status
Practice
POJ 1321
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
深度搜索,递归解决
递归终止条件:棋子已下完,搜索越界,当前搜索坐标已被访问过。
满足以上任意条件就可以结束当前结点.
搜索时可能出现,棋子下完,棋盘仍然有剩余的情况,此时要接着下一行继续搜索,这样才会得出最多种方法
还有递归的时候,千万别一层层的想那么深,那只会让人抓狂,毕竟人脑不是CPU。
实现递归时,人脑的思维只需要着重实现一层,再往下交给计算机就行。
代码
搜索问题确实有一定的套路可循
Time Limit:1000MS Memory Limit:10000KB 64bit IO Format:%I64d & %I64u
Submit
Status
Practice
POJ 1321
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
深度搜索,递归解决
递归终止条件:棋子已下完,搜索越界,当前搜索坐标已被访问过。
满足以上任意条件就可以结束当前结点.
搜索时可能出现,棋子下完,棋盘仍然有剩余的情况,此时要接着下一行继续搜索,这样才会得出最多种方法
还有递归的时候,千万别一层层的想那么深,那只会让人抓狂,毕竟人脑不是CPU。
实现递归时,人脑的思维只需要着重实现一层,再往下交给计算机就行。
代码
#include<stdio.h> #include<string.h> #include<string> #include<stack> #include<queue> #include<math.h> #include<limits.h> //#include<malloc.h>//加上这个头文件会编译错误,原因不明 #include<iostream> #include<algorithm> using namespace std; char map[10][10];//接收地图 int visited[10];//当前列已访问标记为0,未访问标记为1 int sum;//记录方法总数 int n;//地图大小 int k;//棋子数量 void DFS(int line,int num)//传入当前行和已用棋子数 { if(num==k)//如果棋子用完 { sum++;//方法总数加一 return;//结束当前递归 } if(line>=n)//如果搜索越界 return;//结束搜索 for(int i=0;i<n;i++)//棋子没用完,搜索没越界,那就继续搜索 { if(visited[i]==1&&map[line][i]=='#')//坐标可被访问且未被访问过 { visited[i]=0;//先标记当前坐标为已访问,因为后面还要递归搜索 DFS(line+1,num+1);//行数加一,已用棋子数加一,继续搜索 visited[i]=1;//完成一遍后,vsited全部标记为未访问,准备为寻找下一种方法继续标记 } } DFS(line+1,num);//如果未搜索完一遍,棋子就用完了,那就接着下一行搜索新的方式,防止遗漏 return; } int main() { while(~scanf("%d%d",&n,&k)) { if(n==-1&&k==-1) break; for(int i=0;i<n;i++) { for(int j=0;j<n;j++) { cin>>map[i][j];//之前用scanf接收,结果异常,改成cin就没事了,未解之谜。。。。 } } sum=0;//初始化方法总数 for(int i=0;i<10;i++)//当前列未访问标记为1 visited[i]=1; //memset(visited,1,sizeof(visited));//这种初始化方式好像不对,把它注释掉了 DFS(0,0);//从第0行开始搜索,已用棋子数为0 printf("%d\n",sum); } return 0; }
搜索问题确实有一定的套路可循
相关文章推荐
- Remove Linked List Elements
- DFS(深度优先遍历搜索解析)
- PHP变量
- JFinal redis cluster集群插件
- linux下vi命令大全
- 【SpringBoot】ApplicationContextInitializer接口
- 三角剖分算法(delaunay)
- Genymotion的下载安装
- [Objective-C]关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- 20160309,微软3月8日发布13个安全补丁
- 设计模式(九)外观模式Facade(结构型)
- centos下的pcapy安装
- Ubuntu下 嵌入式Qt开发环境的搭建--转载
- iOS证书描述文件说明
- memcpy 与 memmove 区别
- 在Spring中调用基于CXF框架的webService
- 智能指针(三):unique_ptr使用简介
- ssh远程登录linux live系统
- MySQL binlog 组提交与 XA(分布式事务、两阶段提交)【转】
- C# 拆箱与装箱 要严格控制,数量多起来严重影响效率