[openjudge-搜索]深度优先搜索之马走日

题目描述

描述

马在中国象棋以日字形规则移动。请编写一段程序,给定n*m大小的棋盘,以及马的初始位置(xy),要求不能重复经过棋盘上的同一个点,计算马可以有多少途径遍历棋盘上的所有点。

输入

第一行为整数T(T < 10),表示测试数据组数。
每一组测试数据包含一行,为四个整数,分别为棋盘的大小以及初始位置坐标n,m,x,y(0<=x<=n-1,0<=y<=m-1, m < 10, n < 10)

输出

每组测试数据包含一行,为一个整数,表示马能遍历棋盘的途径总数,0为无法遍历一次。

样例输入

1

54 0 0

样例输出

32

题目分析

这是一道十分典型的DFS题,是迷宫的“进化版”。迷宫是往上下左右四个方向行走,同理本题即为往八个方向行走(如图2-1【我已经尽力画了。。】)

设红色坐标为[x,y],这从1-8的坐标依次是[x-1,y+2][x-2,y+1][x-2,y-1][x-1,y-2][x+1,y-2][x+2,y-1][x+2,y+1][x+1,y+2],同理,将其依次存入x[8],y[8]里。

DFS条件判断:不超出边界,不走“回头路”。

DFS退出条件:将整个棋盘摆满即摆放总个数==*

代码实现

#include<iostream>

#include<cstdio>

#include<cstring>

using namespace std;

int n,r,i,j,k,y1,y2,q,w,sn=0;

bool b[105][105];

intx[8]={-2,-1,1,2,2,1,-1,-2},y[8]={1,2,2,1,-1,-2,-2,-1};//存储路径

bool chek(int a,int b)//判断是否超出边界函数

{

        if(a<=r-1&&b<=w-1&&a>=0&&b>=0)return1;

        return0;

}

void s(int str,int stw,int n)

{

        if(n==r*w){sn++;return;}//判断是否已摆满

        for(inti=0;i<=7;i++)

        {

                  if((!b[str+x[i]][stw+y[i]])&&chek(str+x[i],stw+y[i]))

                  {

                           b[str+x[i]][stw+y[i]]=1;

                           s(str+x[i],stw+y[i],n+1);

                           b[str+x[i]][stw+y[i]]=0;//回溯

                  }

        }

}

int main()

{

        intx1,x2;

        scanf("%d",&n);

        for(i=1;i<=n;i++)

        {

                  sn=0;

                  scanf("%d%d%d%d",&r,&w,&x1,&x2);

                  b[x1][x2]=1;

                  s(x1,x2,1);

                  printf("%d\n",sn);

                  memset(b,0,sizeof(b));//一定要记住清零

        }

}

后记

本人第一次写博客,请多指教^_^

Writing by Panda Hu 2017.5.20

转载于:https://www.cnblogs.com/Panda-hu/p/9338335.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值