您的位置:首页 > 其它

杭电OJ第4255题 A Famous Grid

2015-04-15 22:11 260 查看
  杭电OJ第4255题,A Famous Grid题目链接)。

A Famous Grid

Problem Description
Mr. B has recently discovered the grid named "spiral grid".

Construct the grid like the following figure. (The grid is actually infinite. The figure is only a small part of it.)



Considering traveling in it, you are free to any cell containing a composite number or 1, but traveling to any cell containing a prime number is disallowed. You can travel up, down, left or right, but not diagonally. Write a program to find the length of the shortest path between pairs of nonprime numbers, or report it's impossible.



Input
Each test case is described by a line of input containing two nonprime integer 1 ≤ x, y ≤ 10,000.
Output
For each test case, display its case number followed by the length of the shortest path or "impossible" (without quotes) in one line.
Sample Input
1 4

9 32

10 12
Sample Output
Case 1: 1

Case 2: 7

Case 3: impossible
Source
Fudan Local Programming Contest 2012

  解题思路:广度优先搜索(BFS)。把相邻的遍历一遍。如果不是质数,则入队。我的队列用的是STL中的queue来实现的。
  C++语言源代码如下:

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <queue>

using namespace std;

#define MAX_LENGTH 150

typedef int COUNT;
typedef struct { int x, y; } Point;
typedef enum { LEFT, RIGHT, UP, DOWN } DIRECTION;

bool isPrime[MAX_LENGTH * MAX_LENGTH + 1];

inline void getprime (void)
{
COUNT i, j;
const int max_number = MAX_LENGTH * MAX_LENGTH;
memset( isPrime, true, sizeof(isPrime) );
isPrime[0] = false;
isPrime[1] = false;
for ( i = 2; i <= max_number ; i ++ )
{
if ( isPrime[i] )
{
for ( j = ( i << 1 ) ; j <= max_number ; j += i )
isPrime[j] = false;
}
}
}

void init_mat( int mat[MAX_LENGTH][MAX_LENGTH] )
{
COUNT i, j, max_steps_count;
DIRECTION direction;
const int max_number = MAX_LENGTH * MAX_LENGTH;
Point current_postition;

memset( mat, 0, max_number * sizeof(int) );
if ( (MAX_LENGTH & 1) ) // odd number
current_postition.x = current_postition.y = (MAX_LENGTH >> 1);
else
{
current_postition.x = (MAX_LENGTH >> 1);
current_postition.y = current_postition.x - 1;
}

max_steps_count = 1;
j = 0;
direction = RIGHT;
for ( i = 1 ; i <= max_number ; i ++ )
{
if ( isPrime[i] )
mat[current_postition.x][current_postition.y] = 0;
else
mat[current_postition.x][current_postition.y] = i;
j ++;
switch ( direction )
{
case LEFT:
current_postition.y --;
break;
case RIGHT:
current_postition.y ++;
break;
case UP:
current_postition.x --;
break;
case DOWN:
current_postition.x ++;
break;
default:
assert(false);
}
if ( j >= max_steps_count )
{
j = 0;
switch ( direction )
{
case LEFT:
direction = DOWN;
break;
case RIGHT:
direction = UP;
break;
case UP:
max_steps_count ++;
direction = LEFT;
break;
case DOWN:
max_steps_count ++;
direction = RIGHT;
break;
default:
assert(false);
}
}
}
}

inline Point find_position( const int mat[MAX_LENGTH][MAX_LENGTH], const int number )
{
Point result = {-1, -1};
COUNT i, j;
for ( i = 0 ; i < MAX_LENGTH ; i ++ )
{
for ( j = 0 ; j < MAX_LENGTH ; j ++ )
{
if ( mat[i][j] == number )
{
result.x = i;
result.y = j;
return result;
}
}
}
return result;
}

inline void visit( queue <Point> & Q, const int mat[MAX_LENGTH][MAX_LENGTH], int mat_step[MAX_LENGTH][MAX_LENGTH], const Point & position, const int step )
{
if ( position.x < 0 )
return;
if ( position.y < 0 )
return;
if ( position.x >= MAX_LENGTH )
return;
if ( position.y >= MAX_LENGTH )
return;
if ( mat[position.x][position.y] != 0 )
{
if ( mat_step[position.x][position.y] == -1 )
{
mat_step[position.x][position.y] = step;
Q.push(position);
}
else if ( step < mat_step[position.x][position.y] )
{
mat_step[position.x][position.y] = step;
Q.push(position);
}
}
}

int BFS( const int mat[MAX_LENGTH][MAX_LENGTH], const int start, const int end )
{
static int mat_step[MAX_LENGTH][MAX_LENGTH];
Point current_postition, next_position, end_position;
int current_step, next_step;
queue <Point> Q;

end_position = find_position( mat, end );
if ( end_position.x == -1 )
return -1;

memset( mat_step, 0xff, sizeof( mat_step ) );

current_postition = find_position( mat, start );
Q.push( current_postition );
mat_step[current_postition.x][current_postition.y] = 0;

while ( !Q.empty() )
{
current_postition = Q.front();
Q.pop();
current_step = mat_step[current_postition.x][current_postition.y];
next_step = current_step + 1;

// up
next_position.x = current_postition.x - 1;
next_position.y = current_postition.y;
visit( Q, mat, mat_step, next_position, next_step );

// down
next_position.x = current_postition.x + 1;
next_position.y = current_postition.y;
visit( Q, mat, mat_step, next_position, next_step );

// left
next_position.x = current_postition.x;
next_position.y = current_postition.y - 1;
visit( Q, mat, mat_step, next_position, next_step );

// right
next_position.x = current_postition.x;
next_position.y = current_postition.y + 1;
visit( Q, mat, mat_step, next_position, next_step );
}
return mat_step[end_position.x][end_position.y];
}

int main (void)
{
int test_case = 0;
int start, end;
int steps;
static int mat[MAX_LENGTH][MAX_LENGTH];
getprime( );
init_mat( mat );
while ( scanf( "%d%d", &start, &end ) != EOF )
{
test_case ++;
steps = BFS( mat, start, end );
if ( steps < 0 )
printf( "Case %d: impossible\n", test_case );
else
printf( "Case %d: %d\n", test_case, steps );
}
return EXIT_SUCCESS;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: