zoukankan      html  css  js  c++  java
  • FOJ1205 小鼠迷宫问题 (BFD+递推)

    FOJ1205 小鼠迷宫问题 (BFD+递推)

    小鼠a与小鼠b身处一个m×n的迷宫中,如图所示。每一个方格表示迷宫中的一个房间。这m×n个房间中有一些房间是封闭的,不允许任何人进入。在迷宫中任何位置均可沿上,下,左,右4个方向进入未封闭的房间。小鼠a位于迷宫的(p,q)方格中,它必须找出一条通向小鼠b所在的(r,s)方格的路。请帮助小鼠a找出所有通向小鼠b的最短道路。

     

    图 小鼠的迷宫

    编程任务:

    对于给定的小鼠的迷宫,编程计算小鼠a通向小鼠b的所有最短道路。

     

    INPUT

    由文件input.txt给出输入数据。第一行有3个正整数n,m,k,分别表示迷宫的行数,列数和封闭的房间数。接下来的k行中,每行2个正整数,表示被封闭的房间所在的行号和列号。最后的2行,每行也有2个正整数,分别表示小鼠a所处的方格(p,q)和小鼠b所处的方格(r,s)。

     

    OUTPUT:

    将计算出的小鼠a通向小鼠b的最短路长度和有多少条不同的最短路输出到文件output.txt。文件的第一行是最短路长度。文件的第2行是不同的最短路数。

    如果小鼠a无法通向小鼠b则输出“No Solution!”。

    input.txt

    output.txt

    8 8 3

    3 3

    4 5

    6 6

    2 1

    7 7

    11

    96

    解题报告

    看到这个题目,首先给人的第一感觉就是用BFS。初始障碍不能走为-1,一个点向四周扩散。 在数组g上保留广搜的痕迹,即走到每个格子的最短距离。至于路径条数,可以用递推来求。如果一个格子的相邻为其距离减一,即代表这个格子可由其走到。故其方案数为其四周满足的格子的方案数总和。初始起点为1.输出终点即可。算法复杂度为O(n+m)

    附上代码

    #include<bits/stdc++.h>
    #define Pair pair<int,int>
    #define MAXN 100000+1
    #define MAXM 2000000+1
    using namespace std;
    int g[80][80],ans[80][80],n,m,k,s1,s2,e1,e2,qq;
    struct Data{
        int x,y,dis;
    };
    Data make(int x,int y,int dis)
    {
        Data j;j.x=x;j.y=y;j.dis=dis;
        return j;
    }
    void bfs()
    {
        queue <Data> h;
        Data temp;temp.x=s1;temp.y=s2;temp.dis=1;
        g[s1][s2]=1;
        h.push(temp);
        while(h.size()>0)
        {
            Data t=h.front();h.pop();
            
            if(t.x>1&&g[t.x-1][t.y]!=-1&&g[t.x-1][t.y]==0) 
            {h.push(make(t.x-1,t.y,t.dis+1));g[t.x-1][t.y]=t.dis+1;}
            
            if(t.y>1&&g[t.x][t.y-1]!=-1&&g[t.x][t.y-1]==0) 
            {h.push(make(t.x,t.y-1,t.dis+1));g[t.x][t.y-1]=t.dis+1;}
            
            if(t.x<n&&g[t.x+1][t.y]!=-1&&g[t.x+1][t.y]==0) 
            {h.push(make(t.x+1,t.y,t.dis+1));g[t.x+1][t.y]=t.dis+1;}
            
            if(t.y<m&&g[t.x][t.y+1]!=-1&&g[t.x][t.y+1]==0) 
            {h.push(make(t.x,t.y+1,t.dis+1));g[t.x][t.y+1]=t.dis+1;}
            if(g[e1][e2]!=0) 
            {
                printf("%d
    ",g[e1][e2]-1);
                break;
            }
        }
    }
    int answer(int x,int y)
    {
        if(ans[x][y]==0)
        {
        int a=0,b=0,c=0,d=0;
            if(g[x-1][y]+1==g[x][y]) a=answer(x-1,y),ans[x][y]+=a,a=0;
            
            
            if(g[x][y-1]+1==g[x][y]) b=answer(x,y-1),ans[x][y]+=b,b=0;
            
            
            if(g[x+1][y]+1==g[x][y]) c=answer(x+1,y),ans[x][y]+=c,c=0;
            
            if(g[x][y+1]+1==g[x][y]) d=answer(x,y+1),ans[x][y]+=d,d=0;
            
            return ans[x][y];
        }else
        return ans[x][y];
    }
    
    int main()
    {
    
        scanf("%d%d%d",&n,&m,&k);
        for(int i=1;i<=k;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x][y]=-1;
        }
        scanf("%d%d%d%d",&s1,&s2,&e1,&e2);
        bfs();
        ans[s1][s2]=1;
        answer(e1,e2);
        printf("%d
    ",ans[e1][e2]);
    
        return 0;
    }
  • 相关阅读:
    java注解说明
    paypal
    eclispe查看jdk源码后特别卡顿导致未响应解决
    ubuntu+tomcat,多环境、自动化部署脚本,git+maven+tomcat+ubuntu
    ubuntu+let's encrypt生成永久免费https证书 ubuntu+tomcat+nginx+let's encrypt
    MySQL创建数据库与创建用户以及授权
    linux查找并杀死进程shell
    redmine安装笔记
    C#动态获取本机可用串口的两种方式
    C# 控件缩写规范
  • 原文地址:https://www.cnblogs.com/yangyaojia/p/6346497.html
Copyright © 2011-2022 走看看