DFS算法模板(2488:A Knight's Journey)

打印 上一主题 下一主题

主题 917|帖子 917|积分 2751

DFS算法(C++版本)

题目一:

链接:http://bailian.openjudge.cn/practice/2488/


解析思路:

骑士找路就是基本的DFS,用递归不断找到合适的路,找不到就回头直到找到合适的路。
该题难点:要是实现字典序,也就是同样的两种选择,要走到A1而不是B1。所以就有了{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}寻路时走路的尝试走路顺序。注意:我的程序输入的行(m)是表示的数字,列(n)表示的是字母这也是为什么尝试走路的顺序是列小的排在前面优先选择。
代码思路:

根据每次输入的m和n构建棋盘,visit数组默认是全为0,visit数组是棋盘的位置是1,然后经过DFS,走过的棋盘点在visit数组对应的位置置为2,不走走过的棋盘点也就是visit数组是2的点。用road数组记录如果成功走完了棋盘的路径,如果road数组的元素个数不等于m*n(棋盘点的个数),输出impossible,否则输出road数组。完工!!!!!!!!!!!!!!!!!!!
代码实现:

[code]#include#includeusing namespace std;//骑士之旅     http://bailian.openjudge.cn/practice/2488///右(上)上 {1,2}  右(下)上 {2,1}//右(上)下 {2,-1}  右(下)下 {1,-2}//左(上)上 {-1,2}  左(下)上 {-2,1}//左(上)下 {-2,-1} 左(下)下 {-1,-2}char alf[27] = { '0','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z' };int number[10] = { 0,1,2,3,4,5,6,7,8,9 };int visit[11][11];//棋盘点    1表示棋盘   2走过的棋盘点 int road[40];//走的路线   十位表示行   个位表示列 int freq;//用于记录有多少次的输出 int step = 0; //走过了多少步 char re_sign;//0表示没走到头     1表示走到头了 void ways(int i, int j, int m, int n){    //走过的路     visit[j] = 2;    road[step++] = (i + 1) * 10 + (j + 1);//除去i和j为0的情况     //走通了     if (step == m * n)    {        re_sign = 1;        return;    }    //走路的操作    // 数字+字母  字母的字典序优先(A7>B1)    //{-1,-2},{1,-2},{-2,-1},{2,-1},{-2,1},{2,1},{-1,2},{1,2}    if (i - 1 >= 0 && j - 2 >= 0 && visit[i - 1][j - 2] == 1)        ways(i - 1, j - 2, m, n);    if (i + 1 < m && j - 2 >= 0 && visit[i + 1][j - 2] == 1)        ways(i + 1, j - 2, m, n);    if (i - 2 >= 0 && j - 1 >= 0 && visit[i - 2][j - 1] == 1)        ways(i - 2, j - 1, m, n);    if (i + 2 < m && j - 1 >= 0 && visit[i + 2][j - 1] == 1)        ways(i + 2, j - 1, m, n);    if (i - 2 >= 0 && j + 1 < n && visit[i - 2][j + 1] == 1)        ways(i - 2, j + 1, m, n);    if (i + 2 < m && j + 1 < n && visit[i + 2][j + 1] == 1)        ways(i + 2, j + 1, m, n);    if (i - 1 >= 0 && j + 2 < n && visit[i - 1][j + 2] == 1)        ways(i - 1, j + 2, m, n);    if (i + 1 < m && j + 2 < n && visit[i + 1][j + 2] == 1)        ways(i + 1, j + 2, m, n);        if (re_sign == 1)    {        return;    }    //路走不通,把road还原(waiting)     visit[j] = 1;//恢复棋盘点     road[--step] = 0;//把原来记录走路的点恢复,再Sn减1==现走了几步         }int main(){    //要将要输入几组数据     int t;    cin >> t;    while (t--)    {        int m, n;        cin >> m >> n;// m  字母(A B C D) n 数字(1 2 3 4)         cout

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

科技颠覆者

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表