EOJ 3260:袋鼠妈妈找孩子


袋鼠妈妈找孩子

Time limit per test: 1.5 seconds

Time limit all tests: 10.0 seconds

Memory limit: 256 megabytes

袋鼠妈妈找不到她的孩子了。她的孩子被怪兽抓走了。

袋鼠妈妈现在在地图的左上角,她的孩子在地图第  x  行第  y  列的位置。怪兽想和袋鼠妈妈玩一个游戏:他不想让袋鼠妈妈过快地找到她的孩子。袋鼠妈妈每秒钟可以向上下左右四个方向跳一格(如果没有墙阻拦的话),怪兽就要在一些格子中造墙,从而完成一个迷宫,使得袋鼠妈妈能够找到她的孩子,但最快不能小于  k  秒。

请设计这样一个迷宫。

Input

第一行两个整数  n,m   (1n,m8) ,表示地图的总行数和总列数。

第二行三个整数  x,y,k   (1xn,1ym,x+y>1)

Output

输出一个地图,应正好  n  行  m  列。

用 . 表示空地,用 * 表示墙。袋鼠妈妈所在的位置和孩子所在的位置用 . 表示。

数据保证有解。

Examples

input
2 6
1 3 4
output
.*.***
......
比赛的时候出题人发布了公告,说这个题目是多组答案,只要给出任意一个符合条件的答案,都会判为正确。

官方题解:

C. 袋鼠妈妈找孩子

由于数据范围很小,直接搜索就可以了。考虑 DFS,每一个要走的格子,周围最多只能有一格(其实就是走过来的那一格)是走过的。全部搜一遍就结束了。

出题人:过的人少得不可思议。


比赛的时候没有做出来,然后看了官方给的题解之后,有了思路。

思路详述:

暴力求解,搜索一条路径,其从起点到终点的时间大于等于k。当然这个路不是随便选的,走哪是需要条件判断的。为了让袋鼠妈妈沿着我深搜的符合条件的路径走,

我需要采取一些措施,措施如下,假设当前袋鼠妈妈的位置为(x,y),假设她下一秒往右走,那么我就要把(x,y)位置的上方,下方,左方都设成墙,这样的话,

她别无选择了,只能往右走了,同时保留其他三个方向的原始状态,因为回溯的时候还要恢复那三个点的状态。也就是说,搜索方向有四个,如果朝某个方向走,

则除该方向外的其他方向直接封锁,一直这样进行下去,直到找到一条符合条件的路径。在深搜中定义flag变量,标记是否已经找到一组解,当找到第一个符合

条件的解的时候,就把flag变成true.在深搜开始的时候,就先判断flag的值,如果,flag已经是true了,直接返回即可,题目只要一组解,找到解后继续搜索并没有什么

意义而且也浪费时间。


#include<iostream>
#include<stdio.h>
#include<string.h>
using namespace std;

const int maxn = 10;
int Map[maxn][maxn];
int dir[4][2] = {{-1,0},{0,1},{1,0},{0,-1}};  
///搜索方向上、右、下、左。
int n,m;
int x,y,k;
bool flag;     
///用于标记是否已经找到可行解。
/**以sx,sy为新起点进行搜索,并且从起点到(sx,sy)
已经走了step步**/
void dfs(int sx,int sy,int step)  
{
    int a[5]; 
    if(flag)          ///有一组可行解
        return;
    Map[sx][sy] = 1;  ///标记为1,代表这个位置走过了。
    if(sx == x && sy == y)  ///到达目标
    {
        if(step >= k)       ///如果步数大于等于k,是解。
        {
            ///直接输出地图,flag变为true
            for(int i = 1; i <= n; i++)
            {
                for(int j = 1; j <= m; j++)
                {
                    if(Map[i][j]==1 || Map[i][j]==0)
                        printf(".");
                    else
                        printf("*");
                }
                printf("\n");
            }
            flag = true;
        }
        return;  ///找没找到解都要返回
    }
    for(int i = 0; i < 4; i++)  ///进行四个方向的搜索
    {
        int tx = sx + dir[i][0];
        int ty = sy + dir[i][1];
        if(tx>=1&&tx<=n&&ty>=1&&ty<=m&&Map[tx][ty]==0)
        {
            /**为了让袋鼠妈妈走tx,ty这一点,我要逼她无路可走,
            让她只能从(sx,sy)走到(tx,ty),因此封锁(sx,sy)周围除
            (tx,ty)以外的其他点**/
            for(int j = 0; j < 4; j++)  
            {
                if(i == j) continue;
                int tempx = sx + dir[j][0];
                int tempy = sy + dir[j][1];
                a[j] = Map[tempx][tempy]; 
                ///数组a用来保留,(sx,sy)周围点的原始状态,回溯要用到
                if(tempx<1||tempx>n||tempy<1||tempy>m) continue;
                if(Map[tempx][tempy]==0)  ///只有是空地才可以封锁
                    Map[tempx][tempy] = 2;
            }
            dfs(tx,ty,step+1); ///以(tx,ty)为起点,进行深搜
            Map[tx][ty] = 0;   ///回溯,变为0,代表该点没有走过
            for(int j = 0; j < 4; j++)
            {
                if(i == j) continue; 
                int tempx = sx + dir[j][0];
                int tempy = sy + dir[j][1];
                if(tempx<1||tempx>n||tempy<1||tempy>m) continue;
                Map[tempx][tempy] = a[j];  
                ///恢复(sx,sy)周围点的原始状态。
            }
        }
    }
}
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        scanf("%d%d%d",&x,&y,&k);
        memset(Map,0,sizeof(Map));  ///代表这个位置是'.'
        flag = false;
        dfs(1,1,0);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值