zoukankan      html  css  js  c++  java
  • 杭电OJ第4255题 A Famous Grid

      杭电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.)

    entire matrix

    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.

    the matrix where you can go

    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;
    }
  • 相关阅读:
    屏蔽docker镜像暴露的端口
    runtime/cgo: pthread_create failed: Resource temporarily unavailable
    用户状态bash-4.2$
    Datasnap 和mORMOT 性能对比!
    Delphi XE 时间和时间戳互转换
    Delphi XE 10.4.2 IDE 设置----【代码格式化】
    DELPHI XE 数据集合并(TFDLocalSQL)
    CXGRID 常用功能设置
    MSSQL行转列
    delphi xe 获取字符串长度(不足补位)
  • 原文地址:https://www.cnblogs.com/yejianfei/p/2636930.html
Copyright © 2011-2022 走看看