Chapter05-The Game(POJ 1101)

TheGame

Time Limit: 1000MS

Memory Limit: 10000K

Total Submissions: 8767

Accepted: 2674

Description

One morning, you wake up and think: "I am such a goodprogrammer. 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. Eachsquare 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 bya 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 othergame piece. 

The part of the game you have to write now is the one testing whether two gamepieces can be connected according to the rules above.

Input

The input contains descriptions of several different gamesituations. 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 linesdescribe the contents of the board; each of these lines contains exactly wcharacters: a "X" if there is a game piece at this location, and aspace 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 arethe 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 ofgame pieces for a board will be terminated by a line containing "0 0 00". 

The entire input is terminated by a test case starting with w=h=0. This testcase should not be procesed.

Output

For each board, output the line "Board #n:", where n isthe number of the board. Then, output one line for each pair of game piecesassociated with the board description. Each of these lines has to start with"Pair m: ", where m is the number of the pair (starting the countwith 1 for each board). Follow this by "ksegments.", where k is theminimum number of segments for a path connecting the two game pieces, or"impossible.", if it is not possible to connect the two game piecesas 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
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-CentralEuropean Regional Contest 1999

 

题目大意:

         类似连连看,对于指定的图,指定选定两个位置之间的最短步数并求出;(只有拐弯才算一步,允许路径暂时离开游戏板)

 

分析:

         这种类型的题目见过的已经太多了,用暴力搜索BFS,遍历每个起点可以到达位置的步数;若求出第一个到达的步数,那么每次往队列存储的时候,需要判断是否大于这个步数;直到队列为空,退出遍历;

 

Java代码如下:

import java.io.BufferedInputStream;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
public classMain {
 
   private boolean[][] board;
   private int[][] dis;
 
   // 4个方向
   private static int[][] everyCount = { { 0, 1 }, {0, -1 }, { 1, 0 },
        {-1, 0 } };
 
   public Main(int h, int w) {
 
      board = new boolean[w + 2][h + 2];
      dis = new int[w + 2][h + 2];
 
      for (int i = 0; i < w + 2;i++) {
        Arrays.fill(board[i], false);
      }
 
   }
 
   public static void main(String[] args) {
      // TODO Auto-generated method stub
      Scannercin = newScanner(newBufferedInputStream(System.in));
      int h, w;
      h= cin.nextInt();
      w= cin.nextInt();
      Mainma;
      int startx, starty;
      int endx, endy;
      int count = 0;
      int subcount = 0;
      while (!(h == 0 && w== 0)) {
        ma= newMain(h, w);
       
        Stringstr;
        Patternp;
        Matcherm;
        count++;
        cin.nextLine();
        for (int i = 0; i < w; i++) {
           str= cin.nextLine();
           p= Pattern.compile("X");
           m= p.matcher(str);
           while (m.find()) {
              ma.board[i + 1][m.start()+1] = true;
           }
        }
 
        System.out.println("Board #"+ count + ":");
 
        subcount= 0;
        int shortestCount;
        while (true) {
           startx= cin.nextInt();
           starty= cin.nextInt();
 
           endx= cin.nextInt();
           endy= cin.nextInt();
           subcount++;
           if (startx == 0 &&starty == 0 && endx == 0 && endy == 0) {
              break;
           }
           shortestCount= ma.getShortestCount(startx, starty, endx, endy);
 
           System.out.print("Pair "+ subcount + ": ");
 
           if (shortestCount == 1 ||shortestCount == 0) {
              System.out.println(shortestCount +" segments.");
           }elseif(shortestCount == -1) {
              System.out.println("impossible.");
           }else{
              System.out.println(shortestCount +" segments.");
           }
 
        }
        System.out.println();
        h= cin.nextInt();
        w= cin.nextInt();
      }
 
   }
 
   private int getShortestCount(int startw, int starth, int endw, int endh) {
      // TODO Auto-generated method stub
      if(starth == endh&& startw ==endw){
        return 0;
      }
      // 广度遍历
      LinkedList<position>li = newLinkedList<position>();
      li.add(new position(starth,startw));
 
      for (int i = 0; i < dis.length; i++) {
        Arrays.fill(dis[i], -1);
      }
 
      dis[starth][startw] = 0;
      positionvert;
 
      int x, y;
 
      while (li.size() > 0) {
        vert= li.remove();
        for (int i = 0; i < everyCount.length; i++) {
           x= vert.x ;
           y= vert.y ;
           while (true) {
              x= x + everyCount[i][0];
              y= y + everyCount[i][1];
             
              if(x < 0 || x >= board.length || y<0 || y>=board[0].length){
                 break;
              }
             
              if(board[x][y] == true ){
                 //判断该节点所求的节点
                 if(x == endh && y== endw){
                    return dis[vert.x][vert.y] + 1;
                 }
                 break;
              }else if(dis[x][y] == -1 || dis[x][y] > dis[vert.x][vert.y] + 1){
                 dis[x][y] = dis[vert.x][vert.y] + 1;
                 li.add(new position(x, y));
              }
           }
        }
      }
      return -1;
   }
 
   static class position {
 
      int x;
      int y;
 
      public position(int x, int y) {
        this.x = x;
        this.y = y;
      }
   }
 
}





 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值