Uva-816 - Abbott's Revenge

Input

The input file will consist of one or more arrow mazes. The first line of each maze description containsthe name of the maze, which is an alphanumeric string of no more than 20 characters. The next linecontains, in the following order, the starting row, the starting column, the starting direction, the goalrow, and finally the goal column. All are delimited by a single space. The maximum dimensions ofa 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. Thefirst character in the group is ‘N’, ‘S’, ‘E’ or ‘W’ to indicate in what direction of travel the sign wouldbe seen. For example, ‘S’ indicates that this is the sign that is seen when travelling south. (This is thesign posted at the north entrance to the intersection.) Following this first direction character are oneto 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 nextline of the input starts the next maze, and so on. The end of input is the word ‘END’ on a single lineby itself.

Output

For each maze, the output file should contain a line with the name of the maze, followed by one or morelines with either a solution to the maze or the phrase ‘No Solution Possible’. Maze names shouldstart in column 1, and all other lines should start in column 3, i.e., indented two spaces. Solutionsshould be output as a list of intersections in the format (R,C) in the order they are visited from thestart to the goal, should be delimited by a single space, and all but the last line of the solution shouldcontain exactly 10 intersections.

Note:

Robert Abbotts walk-through arrowmazes are actually intended for large-scaleconstruction, not paper. Although hismazes are unpublished, some of them haveactually been built. One of these is on dis-play at an Atlanta museum. Others havebeen constructed by the American MazeCompany over the past two summers. Astheir name suggests these mazes are in-tended to be walked through.

For the adventurous, Figure 2 agraphic of Robert Abbotts Atlanta maze.Solving it is quite difficult, even whenyou have an overview of the entire maze.Imagine trying to solve this by actuallywalking through the maze and only seeingone sign at a time! Robert Abbott him-self indicated that the maze is too com-plex and most people give up before fin-ishing. Among the people that did notgive up was Donald Knuth: it took himabout thirty minutes to solve the maze.

Figure 2: Robert Abbott’s Atlanta Maze

page1image49200

The first maze in the following sample input is the mazein Figure 1.

Sample Input

SAMPLE31N33
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
NOSOLUTION31N32
1 1 WL NR *
1 2 NL ER *
2 1 SL WR NFR *2 2 SR EL *
0
END

Sample Output

Figure 1: An Example Walk-ThroughArrow Maz

page1image56048 page1image56208 page1image56368 page1image56528 page1image57120 page1image57280 page1image57440 page1image58032 page1image58624 page1image59216 page1image59808 page1image60400 page1image60992 page1image61584 page1image61744 page1image61904 page1image62064 page1image62656 page1image63248 page1image63840 page1image64432 page1image65024 page1image65616 page1image66208 page1image66368 page1image66528 page1image66688 page1image66848 page1image67008 page1image67600 page1image68192 page1image68784 page1image68944 page1image69104 page1image69264 page1image69424 page1image69584 page1image69744 page1image69904 page1image70064 page1image70224 page1image70384 page1image70544 page1image70704 page1image70864 page1image71024 page1image71184 page1image71344 page1image71504
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

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
const char* dirT="NWSE";//help change char to int
const char* turnT="FLR";

int di[4]={-1,0,1,0};//when the turn is forward,the change of i seperately in the four different directions
int dj[4]={0,-1,0,1};

int has_edge[10][10][4][3];
int exitp[10][10];
int d[10][10][4];

struct sp
{
    int ic;
    int jc;
    int dir;
};

sp start,endp,startnex;
sp p[10][10][4];//same point may show up twice or more in the answer because it means different directions of the same point

sp next_point(sp u,int dir,int turn)//the dir direction of u
{
    sp v;
    v.dir=dir;
    if(turn==1) v.dir=(dir+1)%4;//when turning left,change the direction(N->E,E->S,S->W,W->N),in other words,make turning left or right become keeping forward.
    if(turn==2) v.dir=(dir+3)%4;//turning right
    //the direction changed is the next point direction
    v.ic=u.ic+di[v.dir];
    v.jc=u.jc+dj[v.dir];
    return v;
}

void print_points()
{
    vector<sp> points;
    sp u=endp;
    while(d[u.ic][u.jc][u.dir]!=0)
    {
        points.push_back(u);
        u=p[u.ic][u.jc][u.dir];
    }
    points.push_back(u);
    points.push_back(start);
    
    int i;
    int cnt=0;
    for(i=(int)(points.size()-1);i>=0;i--)
    {
        if(cnt==0)
            printf(" ");//watch out!two spaces for indentation
        cnt++;
        printf(" (%d,%d)",points[i].ic,points[i].jc);
        if(cnt==10)
        {
            printf("\n");
            cnt=0;
        }
    }
    if(cnt!=0)
    printf("\n");
}

void solve()
{
    queue<sp> q;
    q.push(startnex);
    sp u,v;
    while(!q.empty())
    {
        u=q.front();
        q.pop();
        int pi;
        if(u.ic==endp.ic&&u.jc==endp.jc)
        {
            endp=u;
            print_points();
            return;
        }
         for(pi=0;pi<3;pi++)
        {
            if(has_edge[u.ic][u.jc][u.dir][pi])
            {
                v=next_point(u,u.dir,pi);
                if(exitp[v.ic][v.jc]&&d[v.ic][v.jc][v.dir]<0)
                {
                    q.push(v);
                    d[v.ic][v.jc][v.dir]=d[u.ic][u.jc][u.dir]+1;
                    p[v.ic][v.jc][v.dir]=u;
//                    if(v.ic==endp.ic&&v.jc==endp.jc)
//                    {
//                        endp=v;//refresh the dir of the endp
//                        print_points();
//                        return;
//                    }
                }
            }
            
        }
    }
    printf("  No Solution Possible\n");
}

int main()
{
    string name;
    while(getline(cin,name)&&name!="END")
    {
        cout<<name<<endl;
        memset(d,-1,sizeof(int)*10*10*4);
        char sdir;
        scanf("%d%d",&start.ic,&start.jc);
        exitp[start.ic][start.jc]=1;
        getchar();
        scanf("%c",&sdir);
        int dp;
        dp=(int)(strchr(dirT,sdir)-dirT);
        startnex=next_point(start,dp,0);
        d[startnex.ic][startnex.jc][startnex.dir]=0;
        //d[start.ic][start.jc][start.dir]=0;
        p[startnex.ic][startnex.jc][startnex.dir]=start;
        exitp[startnex.ic][startnex.jc]=1;
        scanf("%d%d",&endp.ic,&endp.jc);
        exitp[endp.ic][endp.jc]=1;
        int ic,jc;
        
        while(scanf("%d%d",&ic,&jc)==2)
        {
            exitp[ic][jc]=1;
            char pdir[10];
            getchar();
            while(scanf("%s",pdir)&&pdir[0]!='*')
            {
                int dirin;
                dirin=(int)(strchr(dirT,pdir[0])-dirT);
                for(int k=1;pdir[k]!='\0';k++)
                {
                    int turnin;
                    turnin=(int)(strchr(turnT,pdir[k])-turnT);
                    has_edge[ic][jc][dirin][turnin]=1;
                }
                    memset(pdir,0,sizeof(char)*10);
                getchar();
            }
        }
        solve();
        name.clear();
        memset(has_edge,0,sizeof(int)*10*10*4*3);
        memset(exitp,0,sizeof(int)*10*10);
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值