您的位置:首页 > 其它

中南大学2012暑期集训中期检测训练赛“跳跳”解题报告

2015-04-15 22:11 459 查看
  中南大学2012暑期集训中期检测训练赛,第H题,跳跳(题目链接)。

跳跳

Description
  一个每块地板标记着0~9某个数字的迷宫,其中标记1的地板不可以走,标记2~9的地板可以不花时间地跳到任意相同数字的位置,也可以和标记0的地板一样向前后左右任意方向花1个单位时间移动1的距离。给出起点和终点,求起点到终点的最短时间。
Input
  每组数据第一行一个n,表示尺寸,2 ≤ n ≤ 100。

  接下来n行每行n个0~9的字符,或S表示起点,E表示终点,S和E的运动规则与0相同。整个地图只有一个S和一个E。
Output
  每组数据输出一个数,占一行,表示起点到终点可以花费的最短时间。

  如果无法到达重点,输出“Oh No!”
Sample Input
5

0S100

00131

00300

00000

003E0

3

S12

010

10E
Sample Output
4

Oh No!

  题意:输入迷宫的值。S为起点,可上下左右走一步,费时为1。E为终点。值为1的点禁止通行。值为2~9的点可以不花时间飞跃到相同值的点,也可上下左右走一步,每步费时为1。值为0的点可上下左右行走一步,每步费时1。求起点到终点至少费时多少。
  解题思路:广度优先搜索。每次遇到0或2~9,就判断耗费时间是否小于这里耗费的时间的暂时最小值,如果小于则替换暂时最小值并判断是否为2~9,如果是,则刷新相同值的全部点。如此往复,直到终点。
  C++源代码如下:

#include <cstdio>
#include <cstdlib>
#include <queue>
#include <cstring>
#include <vector>
#include <climits>

using namespace std;

#define MAX_LENGTH 101

typedef int COUNT;
typedef struct { int x, y, time; } COOR;

char maze[MAX_LENGTH][MAX_LENGTH];
char minMat[MAX_LENGTH][MAX_LENGTH];
vector<COOR> sameCoor[10];

bool visit( queue<COOR> &Q, const int x, const int y, const int time, const int n )
{
COOR next;
if ( x >= 0 && x < n && y >= 0 && y < n )
{
if ( maze[x][y] == 'S' )
return false;
if ( maze[x][y] == 'E' )
return true;
else if ( maze[x][y] == '1' )
return false;
else
{
if ( time < minMat[x][y] )
{
minMat[x][y] = time;
next.x = x;
next.y = y;
next.time = time;
Q.push( next );
if ( maze[x][y] != '0' )
{
int num = maze[x][y] - '0';
for(vector<COOR>::iterator it = sameCoor[num].begin();
it != sameCoor[num].end(); it ++ )
{
next.x = it->x;
next.y = it->y;
next.time = time;
minMat[next.x][next.y] = time;
Q.push( next );
}
}
}
}
}
return false;
}

int BFS( const COOR start, const int n )
{
COOR current;
queue<COOR> Q;

memset( minMat, CHAR_MAX, sizeof(minMat) );
Q.push(start);

while ( !Q.empty() )
{
current = Q.front();
Q.pop();

// left
if ( visit( Q, current.x - 1, current.y, 1 + current.time, n ) )
return 1 + current.time;
// right
if ( visit( Q, current.x + 1, current.y, 1 + current.time, n ) )
return 1 + current.time;
// up
if ( visit( Q, current.x, current.y - 1, 1 + current.time, n ) )
return 1 + current.time;
// down
if ( visit( Q, current.x, current.y + 1, 1 + current.time, n ) )
return 1 + current.time;
}
return -1;
}

int main (void)
{
COUNT i, j;
int n, step;
COOR start;
COOR current;
while ( scanf( "%d", &n ) != EOF )
{
for ( i = 0 ; i < 10 ; i ++ )
sameCoor[i].clear();
for ( i = 0 ; i < n ; i ++ )
{
scanf( "%s", maze[i] );
for ( j = 0 ; j < n ; j ++ )
{
current.x = i;
current.y = j;
current.time = 0;
if ( maze[i][j] == 'S' )
start = current;
else if ( maze[i][j] >= '0' && maze[i][j] <= '9' )
sameCoor[ maze[i][j]-'0' ].push_back( current );
}
}
step = BFS( start, n );
if ( step < 0 )
printf( "Oh No!\n" );
else
printf( "%d\n", step );
}
return EXIT_SUCCESS;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: