CSU-ACM2019寒假集训比赛2-A - Asteroids!

本文详细解析了一道关于在小行星场中寻找最短路径的编程题,使用广度优先搜索(BFS)算法实现。文章提供了完整的代码实现,解释了如何通过队列遍历所有可能的路径,以找到从起点到终点的最少移动次数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这场比赛就AC这一道题,真的好惭愧,dfs和bfs都没学好,尤其是bfs,去看dfs都没时间学bfs,然后就很难受,考试学习bfs,然后勉强A了这道题≡(▔﹏▔)≡

题目:

You’re in space.
You want to get home.
There are asteroids.
You don’t want to hit them.

Input
Input to this problem will consist of a (non-empty) series of up to 100 data sets. Each data set will be formatted according to the following description, and there will be no blank lines separating data sets.

A single data set has 5 components:

Start line - A single line, “START N”, where 1 <= N <= 10.

Slice list - A series of N slices. Each slice is an N x N matrix representing a horizontal slice through the asteroid field. Each position in the matrix will be one of two values: ao
‘O’ - (the letter “oh”) Empty space
‘X’ - (upper-case) Asteroid present

Starting Position - A single line, “A B C”, denoting the <A,B,C> coordinates of your craft’s starting position. The coordinate values will be integers separated by individual spaces.

Target Position - A single line, “D E F”, denoting the <D,E,F> coordinates of your target’s position. The coordinate values will be integers separated by individual spaces.

End line - A single line, “END”

The origin of the coordin’aate system is <0,0,0>. Therefore, each component of each coordinate vector will be an integer between 0 and N-1, inclusive.

The first coordinate in a set indicates the column. Left column = 0.

The second coordinate in a set indicates the row. Top row = 0.

The third coordinate in a set indicates the slice. First slice = 0.

Both the Starting Position and the Target Position will be in empty space.

Output
For each data set, there will be exactly one output set, and there will be no blaink lines sep’sarating output sets.

A single output set consists of a single line. If a route exists, the line will be in the format “X Y”, where X is the same as N from the corresponding input data set and Y is the least number of moves necessary to get your ship from the starting position to the target position. If there is no route from the starting position to the target position, the line will be “NO ROUTE” instead.

A move can only be in one of the six basic directions: up, down, left,b, foaoard, back. Phrased more precisely, a move will either increment or decrement a single component of your current position vector by 1.

Sample Input
START 1
O
0 0 0
0 0 0
END
START 3
XXX
XXX
XXX
OOO
OOO
OOO
XXX
XXX
XXX
0 0 1
2 2 1
END
START 5
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
XXXXX
XXXXX
XXXXX
XXXXX
XXXXX
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
OOOOO
0 0 0
4 4 4
END

Sample Output
1 0
3 4
NO ROUTE

日常翻译:(ง •_•)ง
你在空间。
你想回家。
有小行星。
你不想打’a他们。

输入
这个问题的输入将由一系列(非空的)多达100个数据集组成。每个数据集都将按照以下描述进行格式化,并且没有分隔数据集的空白行。
单个数据集有5个组件:
开始行-单行,“开始N”,其中1 <= N <= 10。
片列表-一系列的N片。每一片都是一个N×N矩阵,表示穿过小行星场的水平切片。矩阵中的每个位置都是两个值之一:
O -(字母“oh”)空格
“X”-(大写)小行星出现
起始位置-一行“A B C”,表示你的飞船起始位置的坐标。坐标值将是由各个空间分隔的整数。
目标位置-一行“D E F”,表示目标位置的坐标。坐标值将是由各个空间分隔的整数。
结束行-单行,“结束”坐标系的原点是<0,0,0>。
因此,每个坐标向量的每个分量都是0到N-1之间的整数,包括。
集合中的第一个坐标表示列。左列= 0。
集合中的第二个坐标表示行。第一行= 0。
集合中的第三个坐标表示切片。第一个切片= 0。
起始位置和目标位置都是空的。

输出
对于每个数据集,只有一个输出集,并且没有分隔输出集的空行。
一个输出集由一行组成。如果存在航线,直线的格式为“X Y”,其中X等于对应输入数据bi集的N, Y是从起始位置到目标位置所需的最少移动数。如果从起始位置到目标位置没有路由,则该线将改为“无路由”。
一个动作只能在六个基本方向之一:上、下、左、右、前、后。更准确地说,移动将使当前位置向量的单个分量增加或减少1。

个人看法:bfs即广度优先搜索,也就是说每一次操作可以将完成多个操作,并且是由顺序的操作(例如迷宫问题到入口的距离,由小到大一点点的操作,因为队列啦~),通过队列,当满足条件的时候就结束,基本模板如下

    BFS(G,s)    
    for each vertex v in V[G]        
    status[v] = WHITE       
    /******其他初始化******/ 
    status[s] = GRAY    //s是原点   
    queue q    
    入队(q,s);
    while (q非空)       
   {
      t = 出队(q);       
      for each vertex v in Adj[t] //与t邻接的点!!          
      if status[v] = WHITE    //只对未访问的操作                
      status[v] = GRAY    //标记为第一次访问               
      /******其他操作******/                
      入队(q,/v)        
      status[t] =/ BLACK   //此点已经处理完了
    }

思路:这道题很明显的就是bfs,就是将从起始点到终点的每一步的到起始点的距离全部遍历一遍,优先输出的即步数最少的,所以就是这样啦~主要是看懂题意

代码如下:

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

char map[20][20][20];
int vis[20][20][20];
int n,sx,sy,sz;
int ex,ey,ez;
int tx[] = {1,-1,0,0,0,0};//将方向全部以数组的形式出来
int ty[] = {0,0,1,-1,0,0};
int tz[] = {0,0,0,0,1,-1};

struct node//用结构体来表示步数,坐标
{
    int x,y,z,step;
};

int check(int x,int y,int z)//检查这个坐标是否满足
{
    if(x<0 || y<0 || z<0 || x>=n || y>=n || z>=n || vis[x][y][z]||map[z][y][x]=='X' )
    return 0;
    return 1;
}

int bfs(int x,int y,int z)
{
    int i;
    queue<node> Q;
    node a,next;//创建分别操作,很不错滴
    a.x = x;
    a.y = y;
    a.z = z;
    a.step = 0;
    vis[x][y][z] = 1;
    Q.push(a);//将起始点入队
    while(!Q.empty())
    {
        a = Q.front();//将第一个结构体赋给a
        Q.pop();
        if(a.x == ex && a.y == ey && a.z == ez)
        return a.step;
        for(i = 0;i<6;i++)//六个方向判断能否放进去
        {
            next = a;//每次都将结构体初始化为a!
            next.x+=tx[i];
            next.y+=ty[i];
            next.z+=tz[i];
            if(check(next.x,next.y,next.z))
            {
                next.step++;//步数加一
                vis[next.x][next.y][next.z] = 1;//标记一下表示走过
                Q.push(next);//队列总是先将步数少的加进去然后先输出少的
            }
        }
    }
    return -1;
}

int main()
{
    char s[10];
    int i,j;
    while(~scanf("%s%d",s,&n))
    {
        for(i = 0;i<n;i++)
        for(j = 0;j<n;j++)
        scanf("%s",map[i][j]);
        scanf("%d%d%d%d%d%d",&sx,&sy,&sz,&ex,&ey,&ez);
        scanf("%s",s);
        int ans = bfs(sx,sy,sz);//最后的步数撒~
        if(ans>=0)
        printf("%d %d\n",n,ans);
        else
        printf("NO ROUTE\n");
    }

    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值