• 跳马(广搜_队列)


    时限:1000ms 内存限制:10000K 总时限:3000ms

    描述:

    在国际象棋中,马的走法与中车象棋类似,即俗话说的“马走日”,下图所示即国际象棋中马(K)在一步能到达的格子(其中黑色的格子是能到达的位置)。

    现有一200*200大小的国际象棋棋盘,棋盘中仅有一个马,给定马的当前位置(S)和目标位置(T),求出马最少需要多少跳才能从当前位置到达目标位置。

    输入:

    本题包含多个测例。输入数据的第一行有一个整数N(1<=N<=1000),表示测例的个数,接下来的每一行有四个以空格分隔的整数,分别表示马当前位置及目标位置的横、纵坐标C(x,y)和G(x,y)。坐标由1开始。

    输出:

    对于每个测例,在单独的一行内输出一个整数,即马从当前位置跳到目标位置最少的跳数。

    输入样例:

    2

    1 1 2 1

    1 5 5 1

    输出样例:

    3

    4

    #include<stdio.h>
    #define n 200
    char a[200][200]={0};//迷宫数组(坐标由0开始)
    int open[2000],openlen=2000,head,tail;
    int Berow,Becol;//起点横纵坐标
    int Enrow,Encol;//终点横,纵坐标
    
    void init();
    int search();
    int emptyopen();
    int takeoutopen();
    int canmoveto(int row,int col,int *p,int *q,int i);//i代表跳马的方向
    int isaim(int row,int col);
    int used(int row,int col);
    void addtoopen(int row,int col);
    /////////////////////////////////////////////////////////////////////////
    int main()
    {
        int m;
        scanf("%d",&m);//m个测例
        for(int i=0;i<m;i++)
        {
            init();
            int temp=search();//若目标节点不可达,则会返回0
            printf("%d\n",temp);
        }    
        return 0;
    }
    void init()//初始化工作
    {
        scanf("%d%d%d%d",&Berow,&Becol,&Enrow,&Encol);//起始点坐标(从1开始的)
        for(int i=0;i<n;i++)
            for(int j=0;j<n;j++)
                a[i][j]=0;//棋盘初始化                
        head=0; tail=1;
        open[0]=(Berow-1)*n+Becol-1;//队列初始化
    }
    ///////////////////////////////////////////////////////////////////
    int search()//寻找最短步长
    {
        int row,col;
        int u,r,c,num=0;
        while(!emptyopen())
        {
            u=takeoutopen();
            row=u/n;  col=u%n;
            num=a[row][col];
            for(int i=0;i<8;i++)//八个方向跳马
            {
                if(canmoveto(row,col,&r,&c,i))
                {
                    if(isaim(r,c))//到达终点                
                        return(num+1);//返回最短步长                
                    else if(!used(r,c))//没到达终点且未走到过
                    {
                        a[r][c]=num+1;//标记走过的点
                        addtoopen(r,c);
                    }
                }
            }
        }
        return 0;//全盘搜索后,还是没有找到通路
    }
    int emptyopen()//判断队列是否为空
    {
        if(head==tail)
            return 1;
        return 0;
    }
    int takeoutopen()//取对列头结点
    {
        int u;
        u=open[head++];
        head=head%openlen;
        return u;
    }
    int canmoveto(int row,int col,int *p,int *q,int i)//i代表跳马的方向
    {
        switch(i)
        {
            case 1: row+=2; col--;   break;//左下1    
            case 2: row++;  col-=2;  break;//左下2    
            case 3: row--;  col-=2;  break;//左上1
            case 4: row-=2; col--;   break;//左上2 
            case 5: row-=2; col++;   break;//右上1
            case 6: row--;  col+=2;  break;//右上2
            case 7: row++;  col+=2;  break;//右下1
            case 8: row+=2; col++;   break;//右下2    
        }
        *p=row;
        *q=col;
        if(row>=0 &&col>=0 &&row<n &&col<n &&a[row][col]==0)
            return 1;
        return 0;
    }
    int isaim(int row,int col)//判断是否到达终点
    {
        if(row==Enrow-1 &&col==Encol-1)
            return 1;
        return 0;
    }
    int used(int row,int col)
    {
        if(a[row][col]==0)
            return 0;
        return 1;
    }
    void addtoopen(int row,int col)//新结点加入队列
    {
        int u=row*n+col;
        open[tail++]=u;
        tail=tail%openlen;
    }
  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 一元三次方程
    Java实现 蓝桥杯VIP 算法训练 乘法表
    Java实现 蓝桥杯VIP 算法训练 矩阵加法
    Java实现 蓝桥杯VIP 算法训练 一元三次方程
    Java实现 蓝桥杯VIP 算法训练 平方计算
    Java实现 蓝桥杯VIP 算法训练 平方计算
    Java实现 蓝桥杯VIP 算法训练 平方计算
    Java实现 蓝桥杯VIP 算法训练 乘法表
    Java实现 蓝桥杯VIP 算法训练 乘法表
    监管只是压倒网盘业务的一根稻草,但不是主要原因(答案只有一个:成本!)
  • 原文地址:https://www.cnblogs.com/IThaitian/p/2593374.html
Copyright © 2020-2023  润新知