FOJ 1205 小鼠迷宫问题

64 篇文章 0 订阅
54 篇文章 0 订阅

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


小鼠的迷宫

编程任务

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

数据输入

本题有多组输入数据,你必须处理到EOF为止。
每组数据的第一行有3个正整数n,m,k,分别表示迷宫的行数,列数和封闭的房间数。接下来的k行中,每行2个正整数,表示被封闭的房间所在的行号和列号。最后的2行,每行也有2个正整数,分别表示小鼠a所处的方格(p,q)和小鼠b所处的方格(r,s)。(1≤p,r≤n; 1≤q,s≤m)

结果输出

对于每组数据,将计算出的小鼠a通向小鼠b的最短路长度和有多少条不同的最短路输出。每组数据输出两行,第一行是最短路长度;第2行是不同的最短路数。每组输出之间没有空行。
如果小鼠a无法通向小鼠b则输出“No Solution!”。

输入文件示例

8 8 3
3 3
4 5
6 6
2 1
7 7

输出文件示例

11
96

Original: FJOI2004

BFS入门的时候做的题,好怀念..............

队列保存状态扩展.............................回溯求解数

(我先感动去了,momo~)

以下是代码:

这个是转来的代码:

  1. #include <stdio.h>
  2. int count[1001][1001];
  3. int que[2][1000000][2];
  4. int main()
  5. {
  6.  int n,m,k;
  7.  int i,j,x,y,startx,starty,endx,endy,step,flag1,flag2,l[2],tx,ty;
  8.  int dx[4]={1,-1,0,0},dy[4]={0,0,1,-1};
  9.  while(scanf("%d %d %d",&n,&m,&k)!=EOF)
  10.  {
  11.   for(i=1;i<=n;i++)
  12.    for(j=1;j<=m;j++)
  13.     count[i][j]=0;
  14.   for(i=1;i<=k;i++)
  15.   {
  16.    scanf("%d %d",&x,&y);
  17.    count[x][y]=-1;
  18.   }
  19.   scanf("%d %d",&startx,&starty);
  20.   scanf("%d %d",&endx,&endy);
  21.   if(startx==endx && starty==endy)
  22.   {
  23.    printf("0/n0/n");
  24.    continue;
  25.   }
  26.   flag1=0;
  27.   l[0]=1;
  28.   l[1]=0;
  29.   que[flag1][0][0]=startx;
  30.   que[flag1][0][1]=starty;
  31.   count[startx][starty]=1;
  32.   step=1;
  33.   while(count[endx][endy]==0)
  34.   {
  35.    flag1=(step+1)%2;
  36.    flag2=step%2;
  37.    if(l[flag1]==0)break;
  38.    for(i=0;i<l[flag1];i++)
  39.    {
  40.     x=que[flag1][i][0];
  41.     y=que[flag1][i][1];
  42.     for(j=0;j<4;j++)
  43.     {
  44.      tx=x+dx[j];
  45.      ty=y+dy[j];
  46.      if(tx<1 || ty<1 || tx>n || ty>m)
  47.       continue;
  48.      if(count[tx][ty]==-1)
  49.       continue;
  50.      if(count[tx][ty]){count[tx][ty]+=count[x][y];continue;}
  51.      else
  52.      {
  53.       que[flag2][l[flag2]][0]=tx;
  54.       que[flag2][l[flag2]][1]=ty;
  55.       l[flag2]++;
  56.       count[tx][ty]+=count[x][y];
  57.      }     
  58.     }    
  59.    }
  60.    step++;
  61.    l[flag1]=0;
  62.   }
  63.   if(count[endx][endy])
  64.    printf("%d/n%d/n",step-1,count[endx][endy]);
  65.   else
  66.    printf("No Solution!/n");
  67.  }
  68.  return 0;
  69. }

这个是我自己写的也:

  1. #include <iostream>
  2. #include <queue>
  3. using namespace std;
  4. #define MAX_MAP_SIZE 101
  5. #define DISABLE_WAY_SIGN -1
  6. #define ABLE_WAY_SIGN 0
  7. /*无法通行*/
  8. struct Point
  9. {
  10.     int x,y;
  11. }tmp;
  12. queue<Point> Queue_Shortest_Way;
  13. int map[MAX_MAP_SIZE][MAX_MAP_SIZE];
  14. int dx[4]={-1,0,1,0};
  15. int dy[4]={0,-1,0,1};
  16. int n,m;/*n_行m_列*/
  17. int num;/*种类个数*/
  18. int sta_x,sta_y,des_x,des_y;
  19. void find_ways_num(int x,int y)
  20. {
  21.     int i;
  22.     if(x==sta_x&&y==sta_y){num++;return;}
  23.     for(i=0;i<4;i++)
  24.         if(map[x+dx[i]][y+dy[i]]==map[x][y]-1) find_ways_num(x+dx[i],y+dy[i]);
  25. }
  26. int main()
  27. {
  28.     int i,j,x,y;
  29.     int k;
  30.     while(scanf("%d%d%d",&n,&m,&k)!=EOF)
  31.     {
  32.         memset(map,ABLE_WAY_SIGN,sizeof(map));
  33.         for(i=0;i<=n+1;i++)
  34.         {
  35.             map[i][0]=DISABLE_WAY_SIGN;
  36.             map[i][m+1]=DISABLE_WAY_SIGN;
  37.         }
  38.         for(j=0;j<=m+1;j++)
  39.         {
  40.             map[0][j]=DISABLE_WAY_SIGN;
  41.             map[n+1][j]=DISABLE_WAY_SIGN;
  42.         }
  43.         for(i=0;i<k;i++)
  44.         {
  45.             scanf("%d%d",&x,&y);
  46.             map[x][y]=DISABLE_WAY_SIGN;
  47.         }
  48.         scanf("%d%d%d%d",&sta_x,&sta_y,&des_x,&des_y);
  49.         tmp.x=sta_x;tmp.y=sta_y;
  50.         map[sta_x][sta_y]=1;
  51.         Queue_Shortest_Way.push(tmp);
  52.         while(!Queue_Shortest_Way.empty())
  53.         {
  54.             for(i=0;i<4;i++)
  55.             {
  56.                 tmp=Queue_Shortest_Way.front();
  57.                 tmp.x+=dx[i];
  58.                 tmp.y+=dy[i];
  59.                 if(map[tmp.x][tmp.y]==ABLE_WAY_SIGN)
  60.                 {
  61.                     Queue_Shortest_Way.push(tmp);
  62.                     map[tmp.x][tmp.y]=map[Queue_Shortest_Way.front().x][Queue_Shortest_Way.front().y]+1;
  63.                 }
  64.             }
  65.             Queue_Shortest_Way.pop();
  66.         }
  67.         num=0;
  68.         if(map[des_x][des_y]==0)printf("No Solution!/n");
  69.         else
  70.         {
  71.             find_ways_num(des_x,des_y);
  72.             printf("%d/n",map[des_x][des_y]-1);
  73.             printf("%d/n",num);
  74.         }
  75.     }
  76.     return 0;
  77. }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值