1. 程式人生 > >51nod 1572 寶島地圖

51nod 1572 寶島地圖

algo [1] stdin osx algorithm gray 我們 tput 同時

1572 寶島地圖技術分享 題目來源: CodeForces 基準時間限制:1 秒 空間限制:131072 KB

勇敢的水手們到達了一個小島,在這個小島上,曾經有海盜在這裏埋下了一些寶藏。然而,我們的船快拋錨了,與此同時,船長發現藏寶圖的一角被老鼠咬掉了一塊。

藏寶圖可以用一個n×m大小的矩形表示。矩形中的每一小塊表示小島中的一小塊陸地(方塊的邊長為1米)。有一些方塊表示的是海,這些塊人是不能通過的。除了海不能走,其它的小方塊都是可以行走的。在可行走區域裏有一些小方塊表示一些已知的地點。

另外,在地圖上有k條指令。每條指令的格式表示如下:

“向y方向走n米”。

這裏的方向有四種:“北”,“南”,“東”,“西”。如果你正確的跟著這些指令行走,並且完整的執行完所有指令,你就可以找到寶藏所在的地點。

但是,很不幸,由於地圖中好多地方都缺失了,船長也不知道從哪些地方開始走。但是船長依然清楚地記得一些已知的地點。另外,船長也知道所有可行走區域。

現在船長想知道從哪些已知地點出發,按照指令,可能找到寶藏所在地。

Input
單組測試數據
第一行包含兩整數n和m(3≤n,m≤1000)。
接下來的n行每行有m個字符,表示整個地圖。
“#”代表海。在地圖矩形中,矩形的四周一圈一定是海。
“.”代表可行走區域,未知地點。大寫字母“A”到“Z”表示可行走區域,已知地點。
所有大寫字母不一定都被用到。每個字母在地圖中最多出現一次。所有已知地點用不同的大寫字母表示。

接下來一行有一個整數k(1≤k≤10^5),接下來有k行。
每行表示一條指令。
指令格式為“dir len”,“dir”表示朝哪個方向走,“len”表示走幾步。
“dir”有四種取值“N”,“S”,“E”,“W”,對應題目中的“北”,“南”,“東”,“西”
在地圖中,北是在頂部,南是在底部,西是在左邊,東是在右邊。“len”是一個整數,範圍在[1,1000]。
Output
共一行,按字典序升序打印出所有可以完整執行地圖中指令的已知區域的字母,如果沒有滿足要求的已知區域,則打印“no solution”(沒有引號)。
Input示例
輸入樣例1
6 10
##########
#K#..#####
#.#..##.##
#..L.#...#
###D###A.#
##########
4
N 2
S 1
E 1
W 2
Output示例
輸出樣例1
AD

先用dp預處理一下每個點向四個方向能走的最遠距離
dp[i][j][0]代表從(i,j)向上最多走多少步,dp[i][j][1]代表從(i,j)向左最多走多少步,dp[i][j][2]代表從(i,j)向下最多走多少步,dp[i][j][3]代表從(i,j)向右最多走多少步

然後就直接模擬就行了
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<algorithm>
#include<iostream>
#include<queue>
#include<map>
#include<cmath>
#include<set>
#include<stack>
#define ll long long
#define max(x,y) (x)>(y)?(x):(y)
#define min(x,y) (x)>(y)?(y):(x)
#define cls(name,x) memset(name,x,sizeof(name))
using namespace std;
const int inf=1<<28;
const int maxn=1010;
const int maxm=110;
const int maxk=100010;
const int mod=1e9+7;
const double pi=acos(-1.0);
int n,m;
char mapp[maxn][maxn];
int dp[maxn][maxn][4];
void init()
{

    //0代表向上,1代表向左
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
        {
            if(mapp[i][j]==#)
                dp[i][j][0]=dp[i][j][1]=-1;
            else
            {
                dp[i][j][0]=dp[i-1][j][0]+1;
                dp[i][j][1]=dp[i][j-1][1]+1;
            }
        }
    //2代表向下,3代表向右
    for(int i=n-1;i>=0;i--)
        for(int j=m-1;j>=0;j--)
        {
            if(mapp[i][j]==#)
                dp[i][j][2]=dp[i][j][3]=-1;
            else
            {
                dp[i][j][2]=dp[i+1][j][2]+1;
                dp[i][j][3]=dp[i][j+1][3]+1;
            }
        }
}
int main()
{
    //freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        int x[30],y[30];
        cls(x,-1);cls(y,-1);
        for(int i=0;i<n;i++)
        {
            scanf("%s",mapp[i]);
            for(int j=0;j<m;j++)
            if(mapp[i][j]>=A&&mapp[i][j]<=Z)
            {
                x[mapp[i][j]-A]=i;
                y[mapp[i][j]-A]=j;
            }
        }
        init();
        int k;
        scanf("%d",&k);
        int dir[maxk],len[maxk];
        for(int i=0;i<k;i++)
        {
            char op[2];
            scanf("%s%d",op,&len[i]);
            if(op[0]==N) dir[i]=0;
            else if(op[0]==W) dir[i]=1;
            else if(op[0]==S) dir[i]=2;
            else if(op[0]==E) dir[i]=3;
        }
        int noso=1;
        for(int i=0;i<26;i++)
        {
            if(x[i]!=-1&&y[i]!=-1)
            {
                int posx=x[i],posy=y[i];
                int flag=1;
                for(int j=0;j<k;j++)
                {
                    if(len[j]>dp[posx][posy][dir[j]])
                        {flag=0;break;}
                    else
                    {
                        if(dir[j]==0) posx-=len[j];
                        else if(dir[j]==1) posy-=len[j];
                        else if(dir[j]==2) posx+=len[j];
                        else if(dir[j]==3) posy+=len[j];
                    }
                }
                if(flag) {noso=0;printf("%c",i+A);}
            }
        }
        if(noso) printf("no solution");
        printf("\n");
    }
    return 0;
}

 

51nod 1572 寶島地圖