The Game

FJNU.1083

Description
One morning, you wake up and think: "I am such a good programmer. Why not make some money?'' So you decide to write a computer game.
The game takes place on a rectangular board consisting of w * h squares. Each square might or might not contain a game piece, as shown in the picture.
One important aspect of the game is whether two game pieces can be connected by a path which satisfies the two following properties:
It consists of straight segments, each one being either horizontal or vertical.
It does not cross any other game pieces.
(It is allowed that the path leaves the board temporarily.)
Here is an example: 
 
The game pieces at (1,3) and at (4, 4) can be connected. The game pieces at (2, 3) and (3, 4) cannot be connected; each path would cross at least one other game piece.
The part of the game you have to write now is the one testing whether two game pieces can be connected according to the rules above.

Input
The input contains descriptions of several different game situations. The first line of each description contains two integers w and h (1 <= w,h <= 75), the width and the height of the board. The next h lines describe the contents of the board; each of these lines contains exactly w characters: a "X" if there is a game piece at this location, and a space if there is no game piece.
Each description is followed by several lines containing four integers x1, y1, x2, y2 each satisfying 1 <= x1,x2 <= w, 1 <= y1,y2 <= h. These are the coordinates of two game pieces. (The upper left corner has the coordinates (1, 1).) These two game pieces will always be different. The list of pairs of game pieces for a board will be terminated by a line containing "0 0 0 0".
The entire input is terminated by a test case starting with w=h=0. This test case should not be procesed.

Output
For each board, output the line "Board #n:", where n is the number of the board. Then, output one line for each pair of game pieces associated with the board description. Each of these lines has to start with "Pair m: ", where m is the number of the pair (starting the count with 1 for each board). Follow this by "ksegments.", where k is the minimum number of segments for a path connecting the two game pieces, or "impossible.", if it is not possible to connect the two game pieces as described above.
Output a blank line after each board.

Sample Input
5 4
XXXXX
X   X
XXX X
 XXX
2 3 5 3
1 3 4 4
2 3 3 4
0 0 0 0
0 0

Sample Output
Board #1:
Pair 1: 4 segments.
Pair 2: 3 segments.
Pair 3: impossible.

Source
Mid-Central European Regional Contest 1999

My Program

#include < iostream >
#define  N 80
using   namespace  std;
int  w,h,map[N][N];

int  search( int  sc, int  sr, int  ec, int  er)
{
    
int tmp[N][N];
    
int i,j,c,r;
    
for(i=0;i<=h+1;i++)
        
for(j=0;j<=w+1;j++)
            tmp[i][j]
=map[i][j];
    
int front=0,rear=1;
    
int qr[N*N],qc[N*N];
    tmp[sr][sc]
=0;
    qr[
0]=sr;qc[0]=sc;
    
while(front<rear)
    
{
        r
=qr[front];c=qc[front];
        j
=c-1;
        
while(j>=0&&(tmp[r][j]>=0||(j==ec&&r==er)))
        
{    
            
if(tmp[r][j]<=0)
            
{
                tmp[r][j]
=tmp[r][c]+1;
                qr[rear]
=r;qc[rear]=j;
                
if(j==ec&&r==er) return tmp[er][ec];
                rear
++;
            }

            j
--;
        }

        j
=c+1;
        
while(j<=w+1&&(tmp[r][j]>=0||(j==ec&&r==er)))
        
{    
            
if(tmp[r][j]<=0)
            
{
                tmp[r][j]
=tmp[r][c]+1;
                qr[rear]
=r;qc[rear]=j;
                
if(j==ec&&r==er) return tmp[er][ec];
                rear
++;
            }

            j
++;
        }

        i
=r-1;
        
while(i>=0&&(tmp[i][c]>=0||(i==er&&c==ec)))
        
{    
            
if(tmp[i][c]<=0)
            
{
                tmp[i][c]
=tmp[r][c]+1;
                qr[rear]
=i;qc[rear]=c;
                
if(i==er&&c==ec) return tmp[er][ec];
                 rear
++;
            }

            i
--;
        }

        i
=r+1;
        
while(i<=h+1&&(tmp[i][c]>=0||(i==er&&c==ec)))
        
{    
            
if(tmp[i][c]<=0)
            
{
                tmp[i][c]
=tmp[r][c]+1;
                qr[rear]
=i;qc[rear]=c;
                
if(i==er&&c==ec) return tmp[er][ec];
                 rear
++;
            }

            i
++;
        }

        front
++;
    }

    
return 0;
}


int  main()
{
    
int k,t=0;
    
int i,j,x;
    
char c[N];
    
int sc,sr,ec,er;
    
while(cin>>w>>h)
    
{
        
if(w==0&&h==0)
            
break;
        memset(map,
0,sizeof(map));
        getchar();
        
for(i=1;i<=h;i++)
        
{
            gets(c);
            
for(j=1;j<=w;j++)
                map[i][j]
=c[j-1]=='X'?-1:0;
        }

        cout
<<"Board #"<<++t<<":"<<endl;
        k
=0;
        
while(cin>>sc>>sr>>ec>>er)
        
{
            
if(sc==0&&sr==0&&ec==0&&er==0)
                
break;
            cout
<<"Pair "<<++k<<"";
            x
=search(sc,sr,ec,er);
            
if(x==0)
                cout
<<"impossible."<<endl;
            
else
                cout
<<x<<" segments."<<endl;
        }

        cout
<<endl;
    }

    
return 0;
}

 

YOYO's Note:
┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄它是华丽的分隔线

【题意简述】

有一张w*h的棋盘,上面的每一格都有可能放一块游戏棋,也有可能不放。
给你两个游戏棋的位置,找出将它们连接起来最少需要的线段数。


【粗略分析】

变形的BFS。线段可以走很长,
因此每一步都是用循环,找出能走到的最远的距离,遇到X或边界结束循环,找下面N个可能走到的点。
走到终点即可返回,走到最后也未到即返回0表示impossible.

【C++源代码】

#include < iostream >
#define  N 80
using   namespace  std;
int  w,h,map[N][N];

int  search( int  sc, int  sr, int  ec, int  er)
{
    
int tmp[N][N];
    
int i,j,c,r;
    
for(i=0;i<=h+1;i++)
        
for(j=0;j<=w+1;j++)
            tmp[i][j]
=map[i][j];
    
int front=0,rear=1;
    
int qr[N*N],qc[N*N];
    tmp[sr][sc]
=0;
    qr[
0]=sr;qc[0]=sc;
    
while(front<rear)
    
{
        r
=qr[front];c=qc[front];
        j
=c-1;
        
while(j>=0&&(tmp[r][j]>=0||(j==ec&&r==er)))
        
{    
            
if(tmp[r][j]<=0)
            
{
                tmp[r][j]
=tmp[r][c]+1;
                qr[rear]
=r;qc[rear]=j;
                
if(j==ec&&r==er) return tmp[er][ec];
                rear
++;
            }

            j
--;
        }

        j
=c+1;
        
while(j<=w+1&&(tmp[r][j]>=0||(j==ec&&r==er)))
        
{    
            
if(tmp[r][j]<=0)
            
{
                tmp[r][j]
=tmp[r][c]+1;
                qr[rear]
=r;qc[rear]=j;
                
if(j==ec&&r==er) return tmp[er][ec];
                rear
++;
            }

            j
++;
        }

        i
=r-1;
        
while(i>=0&&(tmp[i][c]>=0||(i==er&&c==ec)))
        
{    
            
if(tmp[i][c]<=0)
            
{
                tmp[i][c]
=tmp[r][c]+1;
                qr[rear]
=i;qc[rear]=c;
                
if(i==er&&c==ec) return tmp[er][ec];
                 rear
++;
            }

            i
--;
        }

        i
=r+1;
        
while(i<=h+1&&(tmp[i][c]>=0||(i==er&&c==ec)))
        
{    
            
if(tmp[i][c]<=0)
            
{
                tmp[i][c]
=tmp[r][c]+1;
                qr[rear]
=i;qc[rear]=c;
                
if(i==er&&c==ec) return tmp[er][ec];
                 rear
++;
            }

            i
++;
        }

        front
++;
    }

    
return 0;
}


int  main()
{
    
int k,t=0;
    
int i,j,x;
    
char c[N];
    
int sc,sr,ec,er;
    
while(cin>>w>>h)
    
{
        
if(w==0&&h==0)
            
break;
        memset(map,
0,sizeof(map));
        getchar();
        
for(i=1;i<=h;i++)
        
{
            gets(c);
            
for(j=1;j<=w;j++)
                map[i][j]
=c[j-1]=='X'?-1:0;
        }

        cout
<<"Board #"<<++t<<":"<<endl;
        k
=0;
        
while(cin>>sc>>sr>>ec>>er)
        
{
            
if(sc==0&&sr==0&&ec==0&&er==0)
                
break;
            cout
<<"Pair "<<++k<<"";
            x
=search(sc,sr,ec,er);
            
if(x==0)
                cout
<<"impossible."<<endl;
            
else
                cout
<<x<<" segments."<<endl;
        }

        cout
<<endl;
    }

    
return 0;
}

【注意事项】

※ 多组数据,注意清0
※ 注意XX时线段数为1
※ 读入数据去掉换行时用getchar()

【点评】

有些迟钝的一题 = = || 比赛时没有看,今天才完成……

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是一个简单的C++实现Game of Life的示例代码: ```c++ #include <iostream> #include <cstdlib> #include <ctime> using namespace std; const int ROWS = 20; const int COLS = 60; // 初始化格子 void initializeGrid(bool grid[][COLS]) { srand(time(NULL)); for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { int random = rand() % 10; if (random < 3) { grid[row][col] = true; } else { grid[row][col] = false; } } } } // 显示格子 void displayGrid(bool grid[][COLS]) { for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { if (grid[row][col]) { cout << "*"; } else { cout << " "; } } cout << endl; } } // 计算每个格子周围活细胞的数量 int countNeighbors(bool grid[][COLS], int row, int col) { int count = 0; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { int neighborRow = row + i; int neighborCol = col + j; if (neighborRow >= 0 && neighborRow < ROWS && neighborCol >= 0 && neighborCol < COLS) { if (i != 0 || j != 0) { if (grid[neighborRow][neighborCol]) { count++; } } } } } return count; } // 更新格子 void updateGrid(bool grid[][COLS]) { bool newGrid[ROWS][COLS]; for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { int neighbors = countNeighbors(grid, row, col); if (grid[row][col]) { if (neighbors == 2 || neighbors == 3) { newGrid[row][col] = true; } else { newGrid[row][col] = false; } } else { if (neighbors == 3) { newGrid[row][col] = true; } else { newGrid[row][col] = false; } } } } for (int row = 0; row < ROWS; row++) { for (int col = 0; col < COLS; col++) { grid[row][col] = newGrid[row][col]; } } } // 主函数 int main() { bool grid[ROWS][COLS]; initializeGrid(grid); while (true) { system("cls"); // 清屏 displayGrid(grid); updateGrid(grid); } return 0; } ``` 以上代码使用二维布尔数组来表示格子的状态,并且使用函数来完成初始化、显示、计算和更新等操作。在主函数中,我们先使用 `initializeGrid` 函数来随机初始化格子的状态,然后使用 `displayGrid` 函数来显示格子,最后使用 `updateGrid` 函数来更新格子的状态。由于Game of Life是一个无限大的世界,因此我们在这里使用了一个简单的循环来模拟它。 需要注意的是,由于在Windows系统中,清屏需要使用 `system("cls")` 命令,因此以上代码只能在Windows系统中运行。如果你想在其他操作系统中运行该代码,需要使用相应的清屏命令。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值