POJ
来源:互联网 发布:好的户型图 知乎 编辑:程序博客网 时间:2024/06/01 08:58
Description
The knight is getting bored of seeing the same black and white squares again and again and has decided to make a journey
around the world. Whenever a knight moves, it is two squares in one direction and one square perpendicular to this. The world of a knight is the chessboard he is living on. Our knight lives on a chessboard that has a smaller area than a regular 8 * 8 board, but it is still rectangular. Can you help this adventurous knight to make travel plans?
Problem
Find a path such that the knight visits every square once. The knight can start and end on any square of the board.
Input
Output
If no such path exist, you should output impossible on a single line.
Sample Input
31 12 34 3
Sample Output
Scenario #1:A1Scenario #2:impossibleScenario #3:A1B3C1A2B4C2A3B1C3A4B2C4
Source
可以说是首个认真进行的DFS练习吧,虽然说是练习,其实写完的代码根本跑不出结果,所以找了大神的帖子看了看,整理了一下思路,免得总是瞎写写个四不像算法:
我认为DFS的一般思路:
1.明确下一个方向是啥,你要进行的下一个动作是要干什么。比如这道题就是,下一步就是马走日,8种走法,需要注意字典序的问题,所以,搜索的顺序要确定好,纵坐标从A到Z,数字横坐标从小到大。
2.我认为主要问题在于不会写代码,所以下面贴出的代码多多少少有些借鉴。
(1)有三件事需要判断,是否搜超界,点是否访问过,是否遍历了整个棋盘,所以可以用一个函数来判断一下我能不能走下一步。
(2)ans数组负责记录你的搜索路线,返回的条件是是否遍历满整个格子,但是要是遍历不满怎么办呢?上面函数的作用就体现出来了,先判断你这个方法是否可行,然后再去搜索,这样,万一出现2*3的格子避免无限递归的尴尬。
(3)写递归类的程序扣得太细容易糊涂,这里对for循环做出如下解释:
搜索八个方向,对于每个方向,都执行一次DFS函数,那么这个函数大致干了些什么?它的作用就是生成一个遍历的方案!
这里加了一个判断条件,就是万一走棋盘外面,或者出现来回走无限递归的情况,我们就不生成方案了。至于那个flag啥用?其实就是一个标记,其实就相当于,你判断完方案不可行了,但是你得发出这个信号。如果全遍历完了,flag才等于1,那个judge函数里的!flag,是指都遍历完了就不能再次DFS走下一步了,所以都遍历完了也在判断范围内。
这就说明,当flag=1时说明这个方案可行,由于咱们按字典序分的搜索方向,所以这就是答案了;
(4)写主函数的时候,对于每个方案都要清空VIS数组,把flag归0,从哪个点开始搜索就带入DFS函数哪个实参,这里由于要求字典序,我们要从A1遍历。刚开始走就是第一步,所以DFS(1,1,1)。
以上是我对参考代码的理解,如果我还是不会写代码,我就还像这么样解释,直到掌握代码该怎么写了。
我的参考过的代码如下(自己写的根本不叫DFS,乱七八糟,明白那个意思但是程序跑了根本出不来结果或者出现奇怪结果,所以不贴了):
#include<iostream>#include<stdio.h>#include<string.h>const int maxn=80;int vis[maxn][maxn];int ans[maxn][2];int s[10][3]={{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2} };int sx,sy;int flag;bool judge(int x, int y){ if(x >= 1 && x <= sx && y >= 1 && y <= sy && !vis[x][y] && !flag) return true; return false;}void DFS(int x,int y,int step){ ans[step][0]=x; ans[step][1]=y; if(sx*sy==step) { flag=1; return; } for(int i=0;i<8;i++) { int dx=x+s[i][0]; int dy=y+s[i][1]; if(judge(dx,dy)) { vis[dx][dy]=1; DFS(dx,dy,step+1); vis[dx][dy]=0; } }}int main(){ int t; scanf("%d",&t); for(int j=1;j<=t;j++) { scanf("%d%d",&sx,&sy); memset(vis,0,sizeof(vis)); flag=0; vis[1][1]=1; DFS(1,1,1); printf("Scenario #%d:\n",j); if(flag) { for(int i=1;i<=sx*sy;i++) { printf("%c%d",ans[i][1]-1+'A',ans[i][0]); } printf("\n\n"); } else printf("impossible\n\n"); } return 0;}
- POJ
- poj
- POJ
- POJ
- poj
- poj
- POJ
- POJ
- poj
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- POJ
- Alamofire源码解读系列(七)之网络监控(NetworkReachabilityManager)
- 饿了么项目---2、项目搭建及本项目设计模块的参考资料
- Java通过认证kerberos连接HDFS
- IDEA安装配置LiveEdit
- BitCoin APIs
- POJ
- Cannot find class [org.apache.commons.dbcp.BasicDataSource] for bean with name 'dataSource' defined
- PHP合并多个数组
- crond和crontab详解
- wait( )和 waitpid( )
- sessionStorage 学习
- bzoj1044 [HAOI2008]木棍分割(滚动+后缀和)
- 拍黄片运行模式
- bootstrap switch 按钮开关初始化加载赋值,ajax点击切换