您的位置:首页 > 编程语言 > C语言/C++

搜索--poj3984 迷宫问题(广搜C+深搜C++)+HDU 1372 Knight Moves

2017-10-23 21:36 549 查看
定义一个二维数组:
int maze[5][5] = {

0, 1, 0, 0, 0,

0, 1, 0, 1, 0,

0, 0, 0, 0, 0,

0, 1, 1, 1, 0,

0, 0, 0, 1, 0,

};


它表示一个迷宫,其中的1表示墙壁,0表示可以走的路,只能横着走或竖着走,不能斜着走,要求编程序找出从左上角到右下角的最短路线。
Input
一个5 × 5的二维数组,表示一个迷宫。数据保证有唯一解。
Output
左上角到右下角的最短路径,格式如样例所示。
Sample Input
0 1 0 0 0
0 1 0 1 0
0 0 0 0 0
0 1 1 1 0
0 0 0 1 0

Sample Output
(0, 0)
(1, 0)
(2, 0)
(2, 1)
(2, 2)
(2, 3)
(2, 4)
(3, 4)
(4, 4)


广搜C代码

#include<stdio.h>

struct note

{

    int x;//横坐标

    int y;//纵坐标

    int f;//父结点位置

    int s;//步数

    int w;//找到最短路径后,记录当前路径的下一步

};

 int main()

{

    struct note que[30]; //最多需要5*5个空间

    int a[6][6]={0},b[6][6]={0};

    int next[4][2]={0,1,1,0,0,-1,-1,0}; //往四个方向走

    int head,tail;

    int i,j,k,p,q,tx,ty,flag;

    for(i=0;i<5;i++)

        for(j=0;j<5;j++)

         scanf("%d",&a[i][j]);

    head=1;

    tail=1;

    que[tail].x=0;

    que[tail].y=0;

    que[tail].f=0;

    que[tail].s=0;

    tail++;

    b[0][0]=1;

    flag=0; //在到达终点后用作标记

    while(head<tail)  //无路可走跳出循环,本题可改为1

    {

        for(k=0;k<3;k++){

            tx=que[head].x+next[k][0];

            ty=que[head].y+next[k][1];

            if(tx<0||tx>4||ty<0||ty>4) continue;

            if(a[tx][ty]==0&&b[tx][ty]==0)

            {

                b[tx][ty]=1;

                que[tail].x=tx;

                que[tail].y=ty;

                que[tail].f=head;

                que[tail].s=que[head].s+1;

                tail++;

            }

            if(tx==4&&ty==4){ flag=1; break; } //到达终点

        }

        if(flag==1)

        break;

        head++;

    }

    tail--;

    p=tail;

    while(tail!=0) //从(4,4)往上寻找父结点,que[tail].w保存路径

    {

        q=tail;

        tail=que[q].f;

        que[tail].w=q;

    }

    tail=1;

    while(tail!=p){  //输出路径

        printf("(%d, %d)\n",que[tail].x,que[tail].y);

        tail= que[tail].w;

    }

    printf("(4, 4)\n");

    return 0;

}

深搜C++代码

#include<iostream>

#include<string.h>

using namespace std;

int maxn=10010;

int a[5][5],v[5][5],v1[5][5];

int f[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

int l=1;

int Judge(int x1,int y1)//判断函数,判断是否计算越界和判断是否具有继续下一步的通路。

{

    if(x1<0||x1>=5||y1<0||y1>=5)return 0;//判断越界

    if(a[x1][y1]==1||v[x1][y1]>0)return 0;//判断下一个方向是否是通路。

    return 1;

}

void dfs(int x,int y)//优先深度搜索函数

{

    if(x==4&&y==4){//输出方阵形式的通路

        if(l<maxn){

            maxn=l;

            memcpy(v1,v,sizeof(v1));

        }

        return;

    }

    for(int k=1;k<4;k++){

        int x1,y1;

        x1=x+f[k][0];

        y1=y+f[k][1];

        if(Judge(x1,y1)){

            v[x1][y1]=k;

            l++;

            dfs(x1,y1);

            l--;

            v[x1][y1]=0;

        }

    }

}

int main(){

    for(int i=0;i<5;i++){

        for(int j=0;j<5;j++){

            cin>>a[i][j];

        }

    }

    dfs(0,0);

    int d=v1[4][4];

    int x=4,y=4;

    int k;

    int dir[100][2];

    dir[0][0]=4;

    dir[0][1
b498
]=4;

    for(k=1;;k++){

        x=x-f[d][0];

        y=y-f[d][1];

        dir[k][0]=x;

        dir[k][1]=y;

        d=v1[x][y];

        if(x==0&&y==0)break;

    }

    for(int i=k;i>=0;i--){

        cout<<"("<<dir[i][0]<<", "<<dir[i][1]<<")"<<endl;

    }

}

照着《啊哈算法》敲的广搜

相似题

Background

Mr Somurolov, fabulous chess-gamer indeed, asserts that no one else but him can move knights from one position to another so fast. Can you beat him?

The Problem

Your task is to write a program to calculate the minimum number of moves needed for a knight to reach one point from another, so that you have the chance to be faster than Somurolov.

For people not familiar with chess, the possible knight moves are shown in Figure 1.



Input
The input begins with the number n of scenarios on a single line by itself.

Next follow n scenarios. Each scenario consists of three lines containing integer numbers. The first line specifies the length l of a side of the chess board (4 <= l <= 300). The entire board has size l * l. The second and third line contain pair of integers
{0, ..., l-1}*{0, ..., l-1} specifying the starting and ending position of the knight on the board. The integers are separated by a single blank. You can assume that the positions are valid positions on the chess board of that scenario.

Output
For each scenario of the input you have to calculate the minimal amount of knight moves which are necessary to move from the starting point to the ending point. If starting point and ending point are equal,distance is zero. The
distance must be written on a single line.
Sample Input
3
8
0 0
7 0
100
0 0
30 50
10
1 1
1 1

Sample Output
5
28
0


代码

#include<string.h>
#include<stdio.h>
int b[305][305],a[305][305];
struct note
{
int x;
int y;
int s;
int w;
}que[90000];
int main()
{
int next[8][2]={2,1,1,2,-1,2,2,-1,-2,1,1,-2,-1,-2,-2,-1};
int head,tail;
int i,j,k,p,q,tx,ty,flag,n,l,sa,sb,ea,eb;
scanf("%d",&n);
while(n--){
scanf("%d",&l);
scanf("%d %d",&sa,&sb);
scanf("%d %d",&ea,&eb);
head=1;
tail=1;
que[tail].x=sa;
que[tail].y=sb;
que[tail].s=0;
tail++;
b[sa][sb]=1;
flag=0;
while(head<tail)
{
for(k=0;k<8;k++){
tx=que[head].x+next[k][0];
ty=que[head].y+next[k][1];
if(tx<0||tx>=l||ty<0||ty>=l) continue;
if(a[tx][ty]==0&&b[tx][ty]==0)
{
b[tx][ty]=1;
que[tail].x=tx;
que[tail].y=ty;
que[tail].s=que[head].s+1;
tail++;
}
if(tx==ea&&ty==eb){ flag=1; break; }
}
if(flag==1)
break;
head++;
}
if(sa!=ea||sb!=eb)
printf("%d\n",que[tail-1].s);
else printf("0\n");
memset(&que,0,sizeof(que));
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: