• UVA816-Abbott's Revenge(搜索进阶)


    Problem UVA816-Abbott's Revenge

    Accept: 1010  Submit: 10466

    Time Limit: 3000 mSec

    Problem Description

    The 1999 World Finals Contest included a problem based on a dice maze. At the time the problem was written, the judges were unable to discover the original source of the dice maze concept. Shortly after the contest, however, Mr. Robert Abbott, the creator of numerous mazes and an author on the subject, contacted the contest judges and identified himself as the originator of dice mazes. We regret that we did not credit Mr. Abbott for his original concept in last years problem statement. But we are happy to report that Mr. Abbott has offered his expertise to this years contest with his original and unpublished walk-through arrow mazes. As are most mazes, a walk-through arrow maze is traversed by moving from intersection to intersection until the goal intersection is reached. As each intersection is approached from a given direction, a sign near the entry to the intersection indicates in which directions the intersection can be exited. These directions are always left, forward or right, or any combination of these. Figure 1 illustrates a walk-through arrow maze. The intersections are identified as (row, column) pairs, with the upper left being (1,1). The Entrance intersection for Figure 1 is (3,1), and the Goal intersection is (3,3). You begin the maze by moving north from (3,1). As you walk from (3,1) to (2,1), the sign at (2,1) indicates that as you approach (2,1) from the south (traveling north) you may continue to go only forward. Continuing forward takes you toward (1,1). The sign at (1,1) as you approach from the south indicates that you may exit (1,1) only by making a right. This turns you to the east now walking from (1,1) toward (1,2). So far there have been no choices to be made. This is also the case as you continue to move from (1,2) to (2,2) to (2,3) to (1,3). Now, however, as you move west from (1,3) toward (1,2), you have the option of continuing straight or turning left. Continuing straight would take you on toward (1,1), while turning left would take you south to (2,2). The actual (unique) solution to this maze is the following sequence of intersections: (3,1) (2,1) (1,1) (1,2) (2,2) (2,3) (1,3) (1,2) (1,1) (2,1) (2,2) (1,2) (1,3) (2,3) (3,3). You must write a program to solve valid walk-through arrow mazes. Solving a maze means (if possible) finding a route through the maze that leaves the Entrance in the prescribed direction, and ends in the Goal. This route should not be longer than necessary, of course.

     Input

    The input file will consist of one or more arrow mazes. The first line of each maze description contains the name of the maze, which is an alphanumeric string of no more than 20 characters. The next line contains, in the following order, the starting row, the starting column, the starting direction, the goal row, and finally the goal column. All are delimited by a single space. The maximum dimensions of a maze for this problem are 9 by 9, so all row and column numbers are single digits from 1 to 9. The starting direction is one of the characters N, S, E or W, indicating north, south, east and west, respectively. All remaining input lines for a maze have this format: two integers, one or more groups of characters, and a sentinel asterisk, again all delimited by a single space. The integers represent the row and column, respectively, of a maze intersection. Each character group represents a sign at that intersection. The first character in the group is ‘N’, ‘S’, ‘E’ or ‘W’ to indicate in what direction of travel the sign would be seen. For example, ‘S’ indicates that this is the sign that is seen when travelling south. (This is the sign posted at the north entrance to the intersection.) Following this first direction character are one to three arrow characters. These can be ‘L’, ‘F’ or ‘R’ indicating left, forward, and right, respectively. The list of intersections is concluded by a line containing a single zero in the first column. The next line of the input starts the next maze, and so on. The end of input is the word ‘END’ on a single line by itself.

     Output

     

     Sample Input

    SAMPLE
    3 1 N 3 1
    1 1 WL NR *
    1 2 WLF NR ER *
    1 3 NL ER *
    2 1 SL WR NF *
    2 2 SL WF ELF *
    2 3 SFR EL *
    0
    NOSOLUTUION
    3 1 N 3 2
    1 1 WL NR *
    1 2 NL ER *
    2 1 SL WR NFR *
    2 2 SR EL *
    0
    END

    Sample output

    SAMPLE

      (3,1) (2,1) (1,1) (1,2) (2,2) (2,3) (1,3) (1,2) (1,1) (2,1)

      (2,2) (1,2) (1,3) (2,3) (3,3)

    NOSOLUTION

      No Solution Possible

    题解:加了一些限制条件的BFS,总体来说感觉在考察基本功。如何方便地把字符映射成int类型,如何记录路径,都是一些比较简单的东西,合在一起让这个题略显复杂,一点一点分析,code就好

      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdlib>
      4 #include <cstdio>
      5 #include <queue>
      6 #include <vector>
      7 using namespace std;
      8 
      9 const int maxn = 12;
     10 
     11 struct Point{
     12     int x,y;
     13     int towards;
     14     Point(int x = 0,int y = 0,int towards = 0) :
     15         x(x),y(y),towards(towards) {}
     16 };
     17 
     18 int gra[maxn][maxn][4][3];
     19 bool vis[maxn][maxn][4];
     20 Point pre[maxn][maxn][4];
     21 int sx,sy,ex,ey;
     22 char Dir[10] = {'N','W','S','E'};
     23 char To[10] = {'F','L','R'};
     24 int dr[4][2] = {{-1,0},{0,-1},{1,0},{0,1}};
     25 Point start;
     26 
     27 void output(Point v){
     28     vector<Point> ans;
     29     ans.clear();
     30     while(true){
     31         ans.push_back(v);
     32         //printf("(%d,%d)
    ",v.x,v.y);
     33         v = pre[v.x][v.y][v.towards];
     34         if(v.towards == -1){
     35             ans.push_back(v);
     36             break;
     37         }
     38     }
     39     int cnt = 0;
     40     for(int i = ans.size()-1;i >= 0;i--){
     41         if(cnt%10 == 0) printf(" ");
     42         printf(" (%d,%d)",ans[i].x,ans[i].y);
     43         if(++cnt%10 == 0) printf("
    ");
     44     }
     45     if(ans.size()%10 != 0) printf("
    ");
     46 }
     47 
     48 void bfs(){
     49     queue<Point> que;
     50     que.push(start);
     51     pre[start.x][start.y][start.towards] = Point(sx,sy,-1);
     52     while(!que.empty()){
     53         Point first = que.front();
     54         que.pop();
     55         int x = first.x,y = first.y,to = first.towards;
     56         //printf("x:%d y:%d to:%d
    ",x,y,to);
     57         if(x==ex && y==ey){
     58             output(first);
     59             return;
     60         }
     61         for(int i = 0;i < 3;i++){
     62             Point Next;
     63             if(gra[x][y][to][i]){
     64                 if(i == 1){
     65                     Next.towards = (to+1)%4;
     66                 }
     67                 else if(i == 2) Next.towards = (to+3)%4;
     68                 else Next.towards = to;
     69                 Next.x = x+dr[Next.towards][0],Next.y = y+dr[Next.towards][1];
     70                 if(vis[Next.x][Next.y][Next.towards]) continue;
     71                 pre[Next.x][Next.y][Next.towards] = first;
     72                 que.push(Next);
     73                 vis[Next.x][Next.y][Next.towards] = true;
     74             }
     75         }
     76     }
     77     printf("  No Solution Possible
    ");
     78 }
     79 
     80 int main()
     81 {
     82     //freopen("input.txt","r",stdin);
     83     char str[50];
     84     while(scanf("%s",str)){
     85         if(!strcmp(str,"END")) break;
     86         memset(vis,false,sizeof(vis));
     87         memset(gra,0,sizeof(gra));
     88         memset(pre,0,sizeof(pre));
     89         printf("%s
    ",str);
     90         scanf("%d%d%s%d%d",&sx,&sy,str,&ex,&ey);
     91         int dir = strchr(Dir,str[0])-Dir;
     92         start = Point(sx+dr[dir][0],sy+dr[dir][1],dir);
     93         vis[start.x][start.y][start.towards] = true;
     94         int x,y;
     95         while(scanf("%d",&x) && x){
     96             scanf("%d",&y);
     97             while(~scanf("%s",str) && str[0]!='*'){
     98                 int dir = strchr(Dir,str[0])-Dir;
     99                 for(int i = 1;i < (int)strlen(str);i++){
    100                     gra[x][y][dir][strchr(To,str[i])-To] = 1;
    101                 }
    102             }
    103         }
    104         bfs();
    105     }
    106     return 0;
    107 }
  • 相关阅读:
    TextView-setCompondDrawables用法
    android 相对布局RelativeLayout中的一些属性的使用和实例
    登录时旋转等待效果
    使用slidingmeu_actionbarsherlock_lib的问题和The hierarchy of the type MainActivity is inconsistent
    ActionBarSherlock SlidingMenu整合,解决SlidingMenu example的getSupportActionBar()方法不能用问题
    String,StringBuffer和StringBuilder的区别
    File.separator使用
    Android常用异步任务执行方法
    adb server is out of date. killing...
    adb shell root
  • 原文地址:https://www.cnblogs.com/npugen/p/9512374.html
Copyright © 2020-2023  润新知