S - 鸣人和佐助

S - 鸣人和佐助

题目:
佐助被大蛇丸诱骗走了,鸣人在多少时间内能追上他呢?

已知一张地图(以二维矩阵的形式表示)以及佐助和鸣人的位置。地图上的每个位置都可以走到,只不过有些位置上有大蛇丸的手下,需要先打败大蛇丸的手下才能到这些位置。鸣人有一定数量的查克拉,每一个单位的查克拉可以打败一个大蛇丸的手下。假设鸣人可以往上下左右四个方向移动,每移动一个距离需要花费1个单位时间,打败大蛇丸的手下不需要时间。如果鸣人查克拉消耗完了,则只可以走到没有大蛇丸手下的位置,不可以再移动到有大蛇丸手下的位置。佐助在此期间不移动,大蛇丸的手下也不移动。请问,鸣人要追上佐助最少需要花费多少时间?
Input
输入的第一行包含三个整数:M,N,T。代表M行N列的地图和鸣人初始的查克拉数量T。0 < M,N < 200,0 ≤ T < 10
后面是M行N列的地图,其中@代表鸣人,+代表佐助。*代表通路,#代表大蛇丸的手下。
Output
输出包含一个整数R,代表鸣人追上佐助最少需要花费的时间。如果鸣人无法追上佐助,则输出-1。
Sample Input
样例输入1
4 4 1
#@##
**##
###+


样例输入2
4 4 2
#@##
**##
###+


Sample Output
样例输出1
6

样例输出2
4

代码如下:

#include<iostream>
#include<cstdio>
#include<queue>
#include<cstring>
using namespace std;
#define MAX 250

int M,N,T;
int x,y,x2,y2;
int vis[MAX][MAX][15];
int direction[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};
char a[MAX][MAX];
struct Node
{
    int xx,yy;
    int step;
    int tt;
};

int bfs()
{
	memset(vis,0,sizeof(vis));
    queue<Node> q;
    Node node1,node2;
    node1.xx = x;
    node1.yy = y;
    node1.step = 0;
    node1.tt = T;
    q.push(node1);
    vis[x][y][T] = 1;
    while(!q.empty())
    {
        node1 = q.front();
        q.pop();
        if(node1.xx == x2 && node1.yy == y2) return node1.step;
        for(int i = 0;i < 4;i++)
        {
            int dx = node1.xx + direction[i][0];
            int dy = node1.yy + direction[i][1];
            if(!vis[dx][dy][node1.tt] && dx >= 0 && dx < M && dy >= 0 && dy < N )
            {
                if(node1.tt <= 0 && a[dx][dy] == '#') continue;
                vis[dx][dy][node1.tt] = 1;
                node2.xx = dx;
                node2.yy = dy;
                node2.step = node1.step + 1;
                node2.tt = node1.tt;
                if(a[dx][dy] == '#' && node1.tt > 0) node2.tt = node1.tt - 1;
                q.push(node2);
            }
        }
    }
    return -1;
}

int main()
{
	int res;
    while(~scanf("%d%d%d",&M,&N,&T))
    {
        for(int i = 0;i < M;i++)
        {
            for(int j = 0;j < N;j++)
            {
                cin >> a[i][j];
                if(a[i][j] == '@') x = i,y = j;
                else if(a[i][j] == '+') x2 = i,y2 = j;
            }
        }
        res = bfs();
        cout << res << endl;
    }
    return 0;
}

这道题使用BFS可以完成,这里每次往队列中放入的结点包括横纵坐标以及当时已走步数以及查克拉量,当查克拉不为0的时候,无论什么点都可走,走过‘#’记得让查克拉减1,当查克拉为0是那么就只能走’*’,这时候只需步数加1就可以了.
输出‘-1’的条件,就是当队列为空的时候,也就是鸣人走不到佐助那里就输出-1.

这里需要注意的是:使用vis判重的时候不仅要考虑每个点的坐标位置,还需要考虑处在每个点的时候查克拉的量,因为处在相同的点查克拉的量不同会影响后续的进程。之前wa了好几次就是因为没考虑这点。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python的turtle库是一个用于创建简单图形和动画的模块,非常适合初学者学习编程中的绘图概念。如果你想使用turtle库来画出鸣人这个角色,首先你需要知道鸣人的基本特征,比如他的发型、服装等元素。 以下是一个简化的步骤,展示如何用turtle画出鸣人的大致轮廓: 1. 导入turtle模块并设置画笔大小和颜色: ```python import turtle turtle.speed(1) # 设置画笔速度,0最快,1中等,2慢,3最慢 turtle.pencolor('yellow') # 鸣人的头发通常是黄色 ``` 2. 绘制头部(圆形或椭圆): ```python turtle.begin_fill() turtle.circle(30) # 大致的圆形头 turtle.end_fill() ``` 3. 绘制面部特征(两个小圆作为眼睛,一个长形为嘴巴): ```python turtle.penup() turtle.goto(-15, -10) # 移动到合适位置 turtle.pendown() turtle.circle(5) # 左眼 turtle.penup() turtle.goto(-15, 10) # 右眼 turtle.pendown() turtle.circle(5) turtle.penup() turtle.goto(0, 0) # 嘴巴 turtle.pendown() turtle.forward(20) turtle.right(90) turtle.forward(10) turtle.left(90) turtle.forward(20) ``` 4. 绘制身体和衣服: ```python turtle.penup() turtle.goto(-40, 0) # 移动到身体位置 turtle.pendown() turtle.begin_fill() turtle.circle(60) # 身体 turtle.end_fill() turtle.penup() turtle.goto(-70, -20) # 衣服部分 turtle.pendown() turtle.begin_fill() turtle.color('blue', 'white') # 蓝色上衣 turtle.circle(40) # 上衣轮廓 turtle.end_fill() ``` 5. 最后,你可以添加一些细节,如手脚和标志性的螺旋丸符号,但这会更复杂些。 请注意,由于鸣人形象非常细致,用turtle库可能无法精确还原,但以上代码提供了一个基本的绘画框架。如果你需要进一步了解如何改进细节或想要其他相关问题,请告诉我。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值