宝葫芦

宝葫芦

宝葫芦被放在一个城堡里。城堡由n*m个方格组成,你只能从当前所在的方格跳到相邻的4个方格里,而

且不能跳出城堡的范围。城堡中某些方格里有弹簧,每个弹簧具有一个特定能量p,不同弹簧的p值不一

定相同。如果你跳到一个有弹簧的方格,就会立刻沿着原来运动的方向继续跳p格,如果跳到的方格里又

有弹簧,就马上继续跳,直到跳到一个空的方格或者被墙挡住无法继续前进为止。你能否尽快找到宝葫

芦吗? 输入:第一行有两个整数,n和m(3=<n,m<=100),分别是城堡的行数和列数。其后是一个非负整数k,表示弹簧的个数。在接下来的k行里,每行有三个正数x, y, p,以空格隔开,其中x和y是弹簧的坐标

(2=<x<=n-1, 2=<y<=m-1),p是弹簧的能量。在下面的两行里,分别是你和宝葫芦的坐标。此外,你在空中经过的弹簧对你没有任何影响。已知你、宝葫芦和弹簧的初始位置都不同。x坐标轴的范围是1到n,y坐标轴的范围是1到m。 输出: 最少的步数,或者impossible

注意:输入有多组用例。

测试输入

10 10
2
2 7 5
2 3 3
2 8
1 1
测试输出

3
源代码

#include <stdio.h>    
#include <string.h>    
int que[10002][2];    
int dis[10002];  
int map[102][102];    
int t1[4]={0, 1, 0, -1}, t2[4]={1, 0, -1, 0};   
  
struct point  
{  
    int x;  
    int y;  
    int energy;  
}P;  
   
void push(int *p, int que_s, int x, int y)    
{    
    (*p)++;    
    que[*p][0] = x;    
    que[*p][1] = y;    
    map[x][y] = -1;    
    dis[*p] = dis[que_s] + 1;    
}    
  
int main()    
{    
    int M, N, i, x, y, flag;  
    int spring_number;    
    int que_s = 0, que_e = 0, end_x, end_y;    
    while( scanf("%d %d", &M, &N) != EOF  )   
    {    
        que_s = 0, que_e = 0;  
        memset( map, 0, sizeof(map) );    
        memset( dis, 0, sizeof(dis) );          
        scanf( "%d", &spring_number );    
        for( i = 0; i < spring_number; i++ )  
        {    
            scanf("%d %d %d", &P.x, &P.y, &P.energy);    
            map[P.x][P.y] = P.energy;     
        }            
        scanf("%d %d", &que[0][0], &que[0][1]); //用队列存储位置坐标     
        scanf("%d %d", &end_x, &end_y);  
                 
        map[ que[0][0] ][ que[0][1] ] = -1;    
          
        while( que_s <= que_e )  
        {    
            if( que[que_s][0] == end_x && que[que_s][1] == end_y)  
            {    
                printf("%d\n", dis[que_s]);    
                break;    
            }    
            for( i = 0; i < 4; i++)   
            {    
                x = que[que_s][0] + t1[i];    
                y = que[que_s][1] + t2[i];    
                if( x > 0 && x <= M && y > 0 && y <= N)  
                {    
                    flag = map[x][y];    
                    if( flag == -1) continue;     
                    if( flag == 0) push( &que_e, que_s, x, y );    
                    else{    
                        while( flag != 0 && flag != -1)   
                        {    
                            x += flag * t1[i];     
                            y += flag * t2[i];    
                            if( x > 0 && x <= M && y > 0 && y <= N )    
                                flag = map[x][y];    
                            else break;    
                        }    
                        if( flag == 0 )   
                            push( &que_e, que_s, x, y );     
                        if( flag > 0)   
                        {    
                            if( t1[i] == 0 && t2[i] == 1 )   
                                y = N;    
                            if( t1[i] == 1 && t2[i] == 0 )   
                                x = M;    
                            if( t1[i] == 0 && t2[i] == -1 )   
                                y = 1;    
                            if( t1[i] == -1 && t2[i] == 0 )   
                                x = 1;    
                            if( map[x][y] == 0)   
                                push( &que_e, que_s, x, y );    
                        }    
                    }    
                }    
            }    
            que_s++;    
        }    
        if( que_s > que_e )   
            printf("impossible\n");     
    }    
    return 0;    
}  


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值