湘潭市第二届市赛 I, Robot 上下左右变方向搜索题

I, Robot

Accepted : 56 Submit : 228
Time Limit : 1000 MS Memory Limit : 65536 KB
 

Description

A robot must obey any orders given to it by human beings,

except where such orders would conflict with the First Law.

- Isaac Asimov

 

There is a robot trapped in the maze. Now you have to send out some instructions, telling it how to reach its destination.

 

The maze is an N * M grid. Some of the cells are empty, while others are occupied by the wall. Of course the robot can't move into the wall, and it can't move outside the grid too. The robot can only accept three commands: TURN LEFT, TURN RIGHT and GO. The robot may face to North, South, East or West during the movement. When it receives a TURN LEFT command, it will rotate 90 degree to the left. That is, if it faces to east before the command, it will face to north after the TURN LEFT command. The TURN RIGHT command is almost the same, except that the direction is opposite. When receiving the GO command, the robot will move 1 unit towards its orientation, unless there is a nonempty cell in front of it.

 

Please note the robot is always faces to north at the beginning, i.e., face to the upper border in the maze map. (The maze map will be described below.)

 

You want to use minimum number of instructions, so you should write a program for help.

 

Input

 

The first line of the input contains an integer T (T 15), indicating the number of test cases. Then T cases follow.

 

The first line of each test case contains two integers N and M, indicating the size of the maze. Then N lines followed, each line contains exactly M characters, describing the maze. The '#' indicates the wall, the '.' indicates the empty cell, the 'S' and 'T' indicate the start point and the destination of the robot respectively. There are no other characters in the maze map.

 

The orientation of the maze map is just the same as the common sense. That is, the upper-left corner of the maze map indicates the north-west direction, and the lower-right corner indicates the south-east.

 

You can assume 1 M 100 and 1 N 100. There is exactly one 'S' and one 'T' in the maze.

 

Output

 

Output one line for each test case, indicating the minimum number of instructions needed, or output -1 if it's impossible to reach the robot's destination.

 

Sample Input

 

2

5 5

#####

#...#

#.#.#

#S#T#

#####

4 5

#.#.#

#.#.#

#S#T#

#####

 

Sample Output

 

8

-1

 

Hint: The best instruction sequence for the first sample test case should be: GO, GO, TURN RIGHT, GO, GO, TURN RIGHT, GO, GO. And the length is 8.

 

Sample Input

 
 

Sample Output

 
 

Source

"开启时代杯"湘潭市第二届大学生程序设计大赛 (Internet)
I,robot.
题意:在一个二维地图上,给定起点和终点,问至少需要多少条指令能让一个机器人从起点到终点,指令有三种:
1.向前走  2.向左转  3.向右转。
思路:BFS。记录从4个方向到达每个点所需要的最少指令,以这些值作为Hash值剪枝就可以了。

注意 一开始是向北的



#include<stdio.h>
#include<string.h>
#include<iostream>
#include<queue>
using namespace std;
int dx[] = {1,-1,0,0};
int dy[] = {0,0,-1,1};
int hash[105][105][4];
char as[105][105];
int n,m,si,sj,di,dj;
struct nd
{
    int x,y,dir,st;
}tmp,t;
bool isok(int x,int y)
{
    if(x<0||y<0||x==n||y==m||as[x][y]=='#')return false;
    return true;
}
int bfs()
{
    int i;
    queue<nd>que;
    t.x = si;
    t.y = sj;
    t.dir = 1;
    t.st = 0;
    que.push(t);
    hash[si][sj][0] = hash[si][sj][1] = hash[si][sj][2] = hash[si][sj][3] = 0;
    while(!que.empty())
	{
        t = que.front(); que.pop();
        for(i = 0; i < 4; ++ i){
            tmp.x = t.x + dx[i];
            tmp.y = t.y + dy[i];
            if(isok(tmp.x,tmp.y)){
                tmp.st = t.st + 1;
                tmp.dir = i;
                if(t.dir!=i)tmp.st++;//向左向右指令加1
                if((i==0&&t.dir==1)||(i==1&&t.dir==0)||(i==2&&t.dir==3)||(i==3&&t.dir==2))tmp.st++;//如果从走的是相反的方向,指令再加1
                if(tmp.st<hash[tmp.x][tmp.y][i])
				{
                    que.push(tmp);
                    hash[tmp.x][tmp.y][i] = tmp.st;
                }
            }
        }
    }
    i = 1000000;
    if(i>hash[di][dj][0])i=hash[di][dj][0];
    if(i>hash[di][dj][1])i=hash[di][dj][1];
    if(i>hash[di][dj][2])i=hash[di][dj][2];
    if(i>hash[di][dj][3])i=hash[di][dj][3];
    if(i<1000000)return i;
    return -1;
}
int main()
{
    int i,j,k,t,cas=0;
    scanf("%d",&t);
    while(t--){
        scanf("%d %d",&n,&m);
        for(i = 0; i < n; ++ i)scanf("%s",as[i]);
        for(i = 0; i < n; ++ i)
            for(j = 0; j < m; ++ j)
			{
                if(as[i][j]=='S'){si=i;sj=j;}
                if(as[i][j]=='T'){di=i;dj=j;}
                hash[i][j][0]=hash[i][j][1]=hash[i][j][2]=hash[i][j][3]=1000000;
            }
			k = bfs();
			printf("%d\n",k);
    }
    return 0;
}




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值