hznu 1436 Fairy tale(模拟,变化的地图找宝藏)

It is said that in a school’s underground, there is a huge treasure which can meet any desire of the owner.
The Spy Union (SU) is very interest in this legend. After much investigation, SU finally get the answer and let the youngest spy sneak into the school. That’s why Saya is now here.
Today, Saya found the entrance eventually.
She enters the entrance, and found her in a fairy-tale world.
Welcome!” says a fairy, “I am Ivan. My responsibility is to protect the treasure, and give it to the one who have the ability to own it.”
Then Ivan gives Saya three problems.
With your help, Saya finished the first and the second problem (Problem H and I). Here comes the third. If Saya can solve this problem, the treasure belongs to her.
There is a big maze protecting the treasure. You can assume the maze as an N*N matrix while each element in the matrix might be N (North), S (South), W (West) or E (East). At first, Saya is at the element (1, 1) – the north-west corner, and the treasure is at (N, N) – the south-east corner.
The designer have enchant to this matrix, so that the treasure might move from time to time respecting the following rules:
Suppose the treasure is in an element which marked with E. The treasure might eastward move a cell after a unit time. It is similar to S, W and N.
After a unit time, all the mark will change: E to W, W to S, S to N, and N to E. In another word, suppose an element which marked with E at time 0. At time 1, it might change to W, change to S at time 2, change to N at time 3, change to E at time 4, and so on.
Saya doesn't know the initial status of the marks. She is affected by this rule, but she decides to do something more.
Ivan gave Saya a special prop which called Riki. With Riki’s help, she can get the position of the treasure.
In each unit time, Saya will do all of the following three things:
Firstly, she will check the treasure’s position with Riki.
Secondly, she will move follow the designer’s magic the same with the treasure.(If no element exists in the direction of movement,the movement will be cancelled.)
Thirdly, Saya can either move to one direction (N, S, E, and W) a cell or stay there. Saya prefers to be closer with the treasure; if there are many ways with the same geometrical distance, Saya prefers to stay there than move, prefer E than W, W than N, and N than S. Here we should use the position checked at the first step.
You are given the size of the matrix and all the marks of the elements at time 0. Your task is to simulate Saya and the treasure’s movement, and then tell Saya the result.

输入

The input consists of several test cases.
The first line of input in each test case contains one integer N (0<N30), which represents the size of the matrix.
Each of the next N lines contains a string whose length is N, represents the elements of the matrix. The string only consists of N, E, W and S.
The last case is followed by a line containing one zero.

输出

For each case, print the case number (1, 2 …) and the result of Saya’s explore.
If Saya can get the treasure at step x (x100)(that means at the begainning of time x, Saya and the treasure stay in the same cell), print “Get the treasure! At step x.”. 
If after simulating x (x100) steps, you found out that Saya can't get the treasure, print “Impossible. At step x.” 
If you have simulated 100 steps but don’t know whether Saya can get the treasure, print “Not sure.”
Your output format should imitate the sample output. Print a blank line after each test case.

示例输入

5
EWSSE
NNENN
EENNE
SWSEW
NSNSW

0

示例输出

Case 1:
Get the treasure! At step 12.

提示

 Q&A
      Q: How can I know it’s impossible for Saya to get the treasure?

      A: Suppose at time 5, Saya at (1, 1) while the treasure at (2, 2); at time 13, Saya at (1, 1) while the treasure at (2, 2) again. Since both Saya and the treasure go to the same place and have the same direction again, it is a loop, and they will just repeats the moves forever. So at time 13, we can judge it is impossible.

http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2156

地图每一秒的变化,可以写成(tt+x[sx][sy])%4

大神的详细题解:http://blog.csdn.net/lttree/article/details/23753941?utm_source=tuicool

#include<iostream>    
#include<algorithm>    
#include<string>    
#include<map>    
#include<vector>    
#include<cmath>    
#include<queue>    
#include<string.h>    
#include<stdlib.h>    
#include<stdio.h>  
#define ll long long    
using namespace std;  
int x[501][501];  
int dx[5]={0,0,-1,1,0};  
int dy[5]={1,-1,0,0,0};  
int tt,sx,sy,ex,ey,n;  
struct node{  
    int x3,y3,x4,y4,c;  
    node(int xx=0,int yy=0,int xxx=0,int yyy=0,int cc=0){  
        x3=xx;y3=yy;x4=xxx;y4=yyy;c=cc;  
    }  
    bool operator < (const node &rhs) const { 
        if(rhs.x3 != x3)    
            return rhs.x3 > x3;     
        if(rhs.y3 != y3)    
            return rhs.y3 > y3;  
        if(rhs.x3 != x3)    
            return rhs.x4 > x4;  
        if(rhs.x3 != x3)    
            return rhs.y4 > y4;   
        return rhs.c > c;      
    }     
};  
map<node,int> r;  
int isok(int x,int y){  
    if(x>=0&&x<n&&y>=0&&y<n)  
        return 1;  
    return 0;  
}  
double distance(int x1,int y1,int x2,int y2){  
    return (x1-x2)*(x1-x2)+(y1-y2)*(y1-y2);  
}  
int step(){  
    if(sx==ex&&sy==ey)  
        return 1;  
    int p=(tt+x[sx][sy])%4;  
    if(p==2&&isok(sx+1,sy))  //人的第一步骤
        sx+=1;  
    else if(p==3&&isok(sx-1,sy))  
        sx-=1;  
    else if(p==0&&isok(sx,sy+1))  
        sy+=1;  
    else if(p==1&&isok(sx,sy-1))  
        sy-=1;  
    int a,b;  
    double minn=100000000;  
    int u=0;  
    double y[5];  
    for(int i=0;i<5;++i){   //人的第二步骤(注意有可能不动比动更近,比如11和11)
        if(isok(sx+dx[i],sy+dy[i])){  
            double dis=distance(sx+dx[i],sy+dy[i],ex,ey);  
            y[i]=dis;  
            if(dis<minn){  
                minn=dis;  
                a=sx+dx[i];b=sy+dy[i];  
            }  
        }  
    }  
    sx=a;sy=b;  
    p=(tt+x[ex][ey])%4;  
    if(p==2&&isok(ex+1,ey))    //宝藏走
        ex+=1;  
    else if(p==3&&isok(ex-1,ey))  
        ex-=1;  
    else if(p==0&&isok(ex,ey+1))  
        ey+=1;  
    else if(p==1&&isok(ex,ey-1))  
        ey-=1;  
    r[node(sx,sy,ex,ey,tt%4)]++;  
    if(r[node(sx,sy,ex,ey,tt%4)]>1)  
        return 2;  
    return 0;  
}  
int main(){  
    char a;  
    int cnt=0;  
    while(cin>>n&&n!=0){  
        r.clear();  
        printf("Case %d:\n",++cnt);  
        for(int i=0;i<n;++i){  
            getchar();  
            for(int j=0;j<n;++j){  
                scanf("%c",&a);  
                if(a=='E')  
                    x[i][j]=0;  
                else if(a=='W')  
                    x[i][j]=1;  
                else if(a=='S')  
                    x[i][j]=2;  
                else if(a=='N')  
                    x[i][j]=3;  
            }  
        }  
        sx=0,sy=0,ex=n-1,ey=n-1;  
        tt=-1;  
        while(1){  
            ++tt;  
            int q=step();  
            if(q==1){  
                printf("Get the treasure! At step %d.\n",tt);  
                break;  
            }  
            else if(q==2){  
                printf("Impossible. At step %d.\n",tt);  
                break;  
            }  
            if(tt==99){  
                printf("Not sure.\n");  
                break;  
            }  
        }   
        printf("\n");  
    }   
    return 0;  
} <span style="font-family:Times New Roman, serif;font-size:18px;color:#333333;"><span style="line-height: 18px;">  </span></span>


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值