广搜:codevs-3344(初步bfs)

                一道典型的迷宫问题

小刚在迷宫内,他需要从A点出发,按顺序经过B,C,D……,到达最后一个点,再回到A点。迷宫内有些障碍,问至少走几步。

输入描述 Input Description

第一行有三个数n,m表示迷宫有n行,m列。

第2行到第n+1行,每行m个字符,可能是’A’..’Z’,’2’,’0’ 其中,2表示障碍,0表示可以走。’A’..’Z’也可以走。

输出描述 Output Description

至少走几步可以按规定走完,如果不行,输出“Impossible”

读完题后发现这道题比较吸引人的一点是在同一组数据中需要进行多次bfs,很有趣。

比较坑的地方在于,每一次需要判断是否能到达下一点,如果其中一个点到不了,那么便mission fail~

那么没什么问题啦,贴代码:

(写这道题的时候有点着急,以至于变量使用的有点乱QAQ)

#include<bits/stdc++.h>
using namespace std;
int ans,pre[100100],xz,yz,head,tail,n,m,flag;
int u[10]={1,-1,0,0},p[10]={0,0,1,-1};
int a[8848],b[8848],x[30],y[30];
bool map1[510][510],map2[510][510];
void pro(int num){
    while(pre[num]){
        ++ans;
        num=pre[num];
    }
    return ;
}
void doit(){
    int i;
    do{
        head++;
        for( i = 0 ; i < 4 ; ++i){
            int xk=u[i]+a[head];
            int yk=p[i]+b[head];
            if(xk>=1&&xk<=n&&yk>=1&&yk<=m&&map2[xk][yk]){
                tail++;
                a[tail]=xk;b[tail]=yk;pre[tail]=head;
                map2[xk][yk]=false;
                if(xk==xz&&yk==yz){
                    flag=1;
                    pro(tail);head=tail;
                    break;
                }
            }
        }
    }while(head<tail);
}
void start(){
    int i,j;
    flag=0;
    head=0;tail=1;
    memset(pre,0,sizeof(pre));
    memset(a,0,sizeof(a));
    memset(b,0,sizeof(b));
    memset(map2,true,sizeof(map2));
    for(i = 1 ; i <= n ; ++i)
        for(j = 1 ; j <= m ; ++j)
            map2[i][j]=map1[i][j];

}
int main(){
    int j,sum=0;
    char s[100];
    memset(map1,true,sizeof(map1));
    scanf("%d%d",&n,&m);
    for(int i = 1 ; i <= n ; ++i){
        scanf("%s",s);
        for( j = 1 ; j <= m ; ++j){
            if(s[j-1]==‘2‘)map1[i][j]=false;
            if(s[j-1]>=65){
                x[s[j-1]-64]=i;
                y[s[j-1]-64]=j;
                sum++;
            }
        }
    }
    for(int i = 1 ; i < sum ; ++i){
        start();
        xz=x[i+1];yz=y[i+1];
        a[tail]=x[i];b[tail]=y[i];pre[tail]=0;
        map2[x[i]][y[i]]=false;
        doit();
        if(!flag){
            printf("Impossible\n");
            return 0;
        }
    }
    start();
    xz=x[1];yz=y[1];
    a[tail]=x[sum];b[tail]=y[sum];pre[tail]=0;
    map2[x[sum]][y[sum]]=false;
    doit();
    if(!flag){
            printf("Impossible\n");
            return 0;
        }
    printf("%d\n",ans);
    return 0;
}
时间: 2024-10-05 18:38:37

广搜:codevs-3344(初步bfs)的相关文章

双向广搜 codevs 3060 抓住那头奶牛

codevs 3060 抓住那头奶牛 USACO 时间限制: 1 s 空间限制: 16000 KB 题目等级 : 黄金 Gold 题目描述 Description 农夫约翰被告知一头逃跑奶牛的位置,想要立即抓住它,他开始在数轴的N 点(0≤N≤100000),奶牛在同一个数轴的K 点(0≤K≤100000).约翰有两种移动方式:1 分钟内从x 点移动到x+1 或x-1:1 分钟内从x 点移动到2x.假设奶牛不会移动,约翰抓住它需要多少时间? 输入描述 Input Description 一行两个

双向广搜+hash+康托展开 codevs 1225 八数码难题

codevs 1225 八数码难题 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题目描述 Description Yours和zero在研究A*启发式算法.拿到一道经典的A*问题,但是他们不会做,请你帮他们.问题描述 在3×3的棋盘上,摆有八个棋子,每个棋子上标有1至8的某一数字.棋盘中留有一个空格,空格用0来表示.空格周围的棋子可以移到空格中.要求解的问题是:给出一种初始布局(初始状态)和目标布局(为了使题目简单,设目标状态为123804765),找

codevs 1225:八数码难题【双向广搜】

这里是传送门 这道题用普通BFS是可以做的,但是很明显没得过,效率太低了.效率更高的算法A*和双向广搜都可取,这写一下双向广搜的. 注意题目中的判重很重要,可以转化成九位数用hash来解决这个问题. #include <set> #include <string> #include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define

hdu 2717 Catch That Cow(广搜bfs)

题目链接:http://i.cnblogs.com/EditPosts.aspx?opt=1 Catch That Cow Time Limit: 5000/2000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7909    Accepted Submission(s): 2498 Problem Description Farmer John has been inform

【判重+广搜(bfs)】魔板

判重+广搜(bfs)]魔板 Time Limit: 1000MS Memory Limit: 32768KB Special Judge 有一个两行四列的魔板,每个格子里有一个1到8的数字(数字唯一),现在我们可以对魔板进行以下操作: 1.交换两行的数字. 2.将第一列移到第二列,第二列到第三列,第三列到第四列,第四列到第一列. 3.将中间四个数顺时针转一次. 现给你初始状态,我末状态请你用最小的步数将它从初始状态变到末状态. 输入: 前两行,每行4个数表示初状态. 后两行,每行4个数表示末状态

算法学习笔记 二叉树和图遍历—深搜 DFS 与广搜 BFS

图的深搜与广搜 马上又要秋招了,赶紧复习下基础知识.这里复习下二叉树.图的深搜与广搜.从图的遍历说起,图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其经典应用走迷宫.N皇后.二叉树遍历等.遍历即按某种顺序访问"图"中所有的节点,顺序分为: 深度优先(优先往深处走),用的数据结构是栈, 主要是递归实现: 广度优先(优先走最近的),用的数据结构是队列,主要是迭代实现: 对于深搜,由于递归往往可以方便的利

hdu 1242:Rescue(BFS广搜 + 优先队列)

Rescue Time Limit : 2000/1000ms (Java/Other)   Memory Limit : 65536/32768K (Java/Other) Total Submission(s) : 14   Accepted Submission(s) : 7 Font: Times New Roman | Verdana | Georgia Font Size: ← → Problem Description Angel was caught by the MOLIGPY

nyist 999 师傅又被妖怪抓走了 【双广搜 || BFS +状态压缩】

题目:nyist 999 师傅又被妖怪抓走了 分析:在一个图中只要看到D点和E点就行的最小步数,看到的定义是:也就是说两个人在同一行或者同一列,并且中间没有障碍物或者没有其他人就可以看到对方. 所以可以先预处理地图,把D点和E点所在的行列的' .'扩展为d和e,然后只要搜到d和e就可以,问题是只有d和e同时搜到才行,直接广搜肯定不行,我们可以在搜到d点之后然后在从当前点广搜e点,或者e点广搜d点,这样第一次搜到的点不一定是最优的,所以需要枚举所有情况才行,时间复杂度较高. 比较好的一种方法是BF

hdu1240/poj2225 BFS广搜的再理解

原题地址 HDUOJ POJ 题目介绍 题意 这同样是一道搜索题,所不同的是要搜索的图是三维的而不是二维的.但这并没什么大的改变,只是增加了两个搜索的方向而已. 陷阱 要注意的地方是,所给出的起点终点的坐标是按照 列,行,层的顺序. 关于BFS 与DFS不同,BFS能保证所搜到的路径一定是最短路径,所以我们不需要维护一个多维(此处为3维)数组来记录访问到每一点的最小步数,只需要维护一个多维数组来标记是否走过就可以了.DFS中是要不停回溯来找最短路径的,但是BFS是不需要的.这是BFS本身的性质所