機器人大盜 RoboThieves

原出處在這裏:DMOJ - CCC '18 S3
這似乎是一個有些冷門的oj。。。

先是看一下題目(翻譯後):

題目背景

機器人Robo在一個工廠裏,偷了很多東西現在要逃出去。

驚了爲什麼我自己程序跑的數據WA了QAQ2333

題目描述

把工廠看爲一個n行m列字符矩陣。
工廠的出口可能在任意一個空地(用 . 表示)上,所以Robo要走所有的空地。Robo從S出發。可能有牆(用W表示),攝像機(用C表示),傳送帶。
攝像機可以拍到它所在行和所在列的狀況(但不能穿牆),Robo不能出現在攝像機視線範圍中,否則就掛了。
Robo不能穿牆,攝像機也不行。Robo只能上下左右移動。
傳送帶有4種:L,R,U,D(左右上下),可能有連續傳送帶,但Robo也可能被永遠卡在傳送帶上?。傳送帶比地面高,所以在上面不會被拍到,但是傳送帶擋不住攝像機視線。
現在請求出,Robo到每個空地的最短步數,傳送帶上不算,如不能到達,輸出-1。

輸入輸出格式

輸入格式:

輸入兩個正整數n,m。
下面n行每行m個字符。
輸出格式:

K行(K表示空地數),每行一個整數表示S到那個點Robo需要的最短步數(不能走到輸出-1),輸出按空地順序(行優先,再列)

對於此題有非常顯然的做法:DFS/BFS,然後我腦抽了竟然用了Dijkstra。。。爲的就是懶得判環了。。。
但這種做法是十分危險的,一定要謹慎:
1.代碼長,方法暴力不好看 (不過看起來倒是很直觀)
2.空間耗得大(不過此題不會MLE)
3.不用堆優化的話時間慢(我還真沒用。。。)不過這個oj速度比較快可以AC。(要是是CCF的老爺機絕對要掛)

有幾個我差點被坑到的地方:我把攝像機視線全設爲牆,但我後來攝像機視線又不能穿牆,導致有地方沒有擋到;還有輸出點的時候應該輸出.的地方不是從第一個點開始。。。

先看容易看懂十分暴力不優美的Dijkstra:(真是喪心病狂)
做好看200+行代碼準備:

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

const int INF=0x7fffffff;

struct edge
{
    int to,cost;
};

int fx[4]={1,0,-1,0};
int fy[4]={0,1,0,-1};
int row,col,d[10001],vis[10001],n,spot[10001],count_;
char a[101][101];
bool visit[10001][10001];
vector<edge> graph[10001];

void dijkstra(int s)
{
    int min1,k;
    for(int i=1;i<=row*col;i++)
        d[i]=INF;
    d[s]=0;
    for(int i=1;i<row*col;i++)
    {
        min1=INF;
        k=s;
        for(int j=1;j<=row*col;j++)
            if(!vis[j] && min1>d[j])
                min1=d[j],k=j;
        vis[k]=1;
        for(int j=0;j<graph[k].size();j++)
        {
            int t=graph[k][j].to;
            if(!vis[t] && min1+graph[k][j].cost<d[t])
                d[t]=min1+graph[k][j].cost;
        }
    }
    return;
}

int main()
{
//  freopen("robothief010.in","r",stdin);
//  freopen("robothief010.out","w",stdout);
    bool flag=true;
    int s;
    cin>>row>>col;
    for(int i=1;i<=row;i++)
        for(int j=1;j<=col;j++)
        {
            cin>>a[i][j];
            if(a[i][j]=='.')
                n++,spot[count_++]=(i-1)*col+j;
            if(a[i][j]=='S')
                s=(i-1)*col+j;
        }
    for(int i=1;i<=row;i++)
        for(int j=1;j<=col;j++)
            if(a[i][j]=='C')
            {
                a[i][j]='K';
                for(int z=i;z<=row && a[z][j]!='W';z++)
                {
                    if(a[z][j]=='.')
                        a[z][j]='K';
                    if(a[z][j]=='S')
                    {
                        for(int h=0;h<n;h++)
                            cout<<"-1"<<endl;
                        return 0;
                    }
                }
                for(int z=i-1;z>=1 && a[z][j]!='W';z--)
                {
                    if(a[z][j]=='.')
                        a[z][j]='K';
                    if(a[z][j]=='S')
                    {
                        for(int h=0;h<n;h++)
                            cout<<"-1"<<endl;
                        return 0;
                    }
                }
                for(int z=j+1;z<=col && a[i][z]!='W';z++)
                {
                    if(a[i][z]=='.')
                        a[i][z]='K';
                    if(a[i][z]=='S')
                    {
                        for(int h=0;h<n;h++)
                            cout<<"-1"<<endl;
                        return 0;
                    }
                }
                for(int z=j-1;z>=1 && a[i][z]!='W';z--)
                {
                    if(a[i][z]=='.')
                        a[i][z]='K';
                    if(a[i][z]=='S')
                    {
                        for(int h=0;h<n;h++)
                            cout<<"-1"<<endl;
                        return 0;
                    }
                }
            }
    for(int i=1;i<=row;i++)
        for(int j=1;j<=col;j++)
            if(a[i][j]=='K')
                a[i][j]='W';
    edge temp;
    for(int i=1;i<=row;i++)
    {
        for(int j=1;j<=col;j++)
        {
            if(a[i][j]=='.' || a[i][j]=='S')
            {
                for(int p=0;p<4;p++)
                    if(i+fx[p]>=1 && i+fx[p]<=row && j+fy[p]>=1 && j+fy[p]<=col && a[i+fx[p]][j+fy[p]]!='W')
                    {
                        if(!visit[(i-1)*col+j][(i+fx[p]-1)*col+j+fy[p]])
                        {
                            visit[(i-1)*col+j][(i+fx[p]-1)*col+j+fy[p]]=true;
                            temp.to=(i+fx[p]-1)*col+j+fy[p];
                            temp.cost=1;
                            graph[(i-1)*col+j].push_back(temp);
                        }
                        if(!visit[(i+fx[p]-1)*col+j+fy[p]][(i-1)*col+j] && a[i+fx[p]][j+fy[p]]=='.')
                        {
                            visit[(i+fx[p]-1)*col+j+fy[p]][(i-1)*col+j]=true;
                            temp.to=(i-1)*col+j;
                            temp.cost=1;
                            graph[(i+fx[p]-1)*col+j+fy[p]].push_back(temp);
                        }
                    }
            }
            else if(a[i][j]!='W' && a[i][j]!='.' && a[i][j]!='S')
            {
                if(a[i][j]=='L')
                {
                    if(j-1<1 || a[i][j-1]=='W')
                    {
                        a[i][j]='W';
                        continue;
                    }
                    if(!visit[(i-1)*col+j][(i-1)*col+j-1])
                    {
                        visit[(i-1)*col+j][(i-1)*col+j-1]=true;
                        temp.to=(i-1)*col+j-1;
                        temp.cost=0;
                        graph[(i-1)*col+j].push_back(temp);
                    }
                }
                if(a[i][j]=='R')
                {
                    if(j+1>col || a[i][j+1]=='W')
                    {
                        a[i][j]='W';
                        continue;
                    }
                    if(!visit[(i-1)*col+j][(i-1)*col+j+1])
                    {
                        visit[(i-1)*col+j][(i-1)*col+j+1]=true;
                        temp.to=(i-1)*col+j+1;
                        temp.cost=0;
                        graph[(i-1)*col+j].push_back(temp);
                    }
                }
                if(a[i][j]=='D')
                {
                    if(i+1>row || a[i+1][j]=='W')
                    {
                        a[i][j]='W';
                        continue;
                    }
                    if(!visit[(i-1)*col+j][(i)*col+j])
                    {
                        visit[(i-1)*col+j][(i)*col+j]=true;
                        temp.to=(i)*col+j;
                        temp.cost=0;
                        graph[(i-1)*col+j].push_back(temp);
                    }
                }
                if(a[i][j]=='U')
                {
                    if(i-1<1 || a[i-1][j]=='W')
                    {
                        a[i][j]='W';
                        continue;
                    }
                    if(!visit[(i-1)*col+j][(i-2)*col+j])
                    {
                        visit[(i-1)*col+j][(i-2)*col+j]=true;
                        temp.to=(i-2)*col+j;
                        temp.cost=0;
                        graph[(i-1)*col+j].push_back(temp);
                    }
                }
            }
        }
    }
    dijkstra(s);
    for(int i=0;i<count_;i++)
    {
        if(spot[i]==s)
            continue;
        if(d[spot[i]]==INF)
            cout<<"-1"<<endl;
        else
            cout<<d[spot[i]]<<endl;
    }
    return 0;
} 

OKay,現在是正常的DFS:(由我們學校一位神犇寫的)
(但其實這個代碼是有點問題的,知道錯在哪裏嘛?)

#include <cstdio>
#include <iostream>
#include <vector>

using namespace std;

int n,m,stx,sty;
char map[102][102];
vector<int> endx;
vector<int> endy;
int sht[102][102];
int mapp[102][102]={0};

void dfs(int x,int y,int step)
{
    if(mapp[x][y]==1)
        return;
    if(step>=sht[x][y])
        return;
    else
        sht[x][y]=step;
    if(map[x][y]=='L')
    {
        dfs(x,y-1,step);
        return;
    }
    if(map[x][y]=='R')
    {
        dfs(x,y+1,step);
        return;
    }
    if(map[x][y]=='U')
    {
        dfs(x-1,y,step);
        return;
    }
    if(map[x][y]=='D')
    {
        dfs(x+1,y,step);
        return;
    }
    if(mapp[x+1][y]==0)
        dfs(x+1,y,step+1);
    if(mapp[x-1][y]==0)
        dfs(x-1,y,step+1);
    if(mapp[x][y+1]==0)
        dfs(x,y+1,step+1);
    if(mapp[x][y-1]==0)
        dfs(x,y-1,step+1);
}
int main()
{
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            cin>>map[i][j];
            if(map[i][j]=='.')
            {
                endx.push_back(i);
                endy.push_back(j);
            }
            if(map[i][j]=='S')
            {
                stx=i;
                sty=j;
            }
            if(map[i][j]=='W')
            {
                mapp[i][j]=1;
            }
            sht[i][j]=30000;
        }
    }
    for(int i=0;i<=n;i++)
        mapp[i][0]=mapp[i][m+1]=1;
    for(int i=0;i<=m;i++)
        mapp[0][i]=mapp[n+1][i]=1;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(map[i][j]=='C')
            {
                for(int x=i;x<=n;x++)
                {
                    if(map[x][j]=='W')
                        break;
                    else if(map[x][j]=='.')
                        mapp[x][j]=1;
                }
                for(int x=i;x>0;x--)
                {
                    if(map[x][j]=='W')
                        break;
                    else if(map[x][j]=='.')
                        mapp[x][j]=1;
                }
                for(int y=j;y<=m;y++)
                {
                    if(map[i][y]=='W')
                        break;
                    else if(map[i][y]=='.')
                        mapp[i][y]=1;
                }
                for(int y=j;y>0;y--)
                {
                    if(map[i][y]=='W')
                        break;
                    else if(map[i][y]=='.')
                        mapp[i][y]=1;
                }
            }
        }
    }
    dfs(stx,sty,0);
    for(int i=0;i<endx.size();i++)
    {
        if(sht[endx[i]][endy[i]]==30000)
            cout<<-1<<endl;
        else
            cout<<sht[endx[i]][endy[i]]<<endl;
    }
    return 0;
}

接下來是我用BFS又寫了一遍:

#include <cstdio>
#include <cstring>
#include <queue>
#include <algorithm>

using namespace std;

const int N=111;
int n,m;
char a[N][N];
int ans[N][N];
int sx=-1,sy;
const int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};

bool checkIn(int x,int y)
{
    return 0<=x && x<n && 0<=y && y<m;
}

void input()
{
    scanf("%d%d",&n,&m);
    for(int i=0;i<n;i++)
    {
        scanf("%s", a[i]);
        for(int j=0;j<m;j++)
        {
            if (a[i][j] == 'S')
                sx = i, sy = j;
            ans[i][j]=-1;
        }
    }
}

struct Point
{
    int x,y;
    Point(int x,int y):x(x),y(y){}
    int getAns()const
    {
        return ans[x][y];
    }
    char get()const
    {
        return a[x][y];
    }
    bool operator<(const Point &p)const
    {
        if(getAns()!=p.getAns())
            return getAns()>p.getAns();
        if(x!=p.x)
            return x<p.x;
        return y<p.y;
    }
};
void bfs(int sx,int sy)
{
    priority_queue<Point> Q;
    ans[sx][sy]=0;
    Q.push(Point(sx,sy));
    while(!Q.empty())
    {
        Point u=Q.top();
        Q.pop();
        int dmin=0,dmax=3;
        if (u.get()=='U')
            dmin=dmax=0;
        else if(u.get()=='D')
            dmin=dmax=1;
        else if(u.get()=='L')
            dmin=dmax=2;
        else if(u.get()=='R')
            dmin=dmax=3;
        for(int d=dmin;d<=dmax;d++)
        {
            Point v(u.x+dir[d][0],u.y+dir[d][1]);
            if(!checkIn(v.x,v.y))
                continue;
            if(v.get()=='W')
                continue;
            if(v.get()=='C')
                continue;
            if(v.getAns()!=-1)
                continue;
            ans[v.x][v.y]=u.getAns()+(a[v.x][v.y]=='.'?1:0);
            Q.push(v);
        }
    }
}

void solve()
{
    bool flag=true;
    for(int i=0;i<n && flag;i++)
        for(int j=0;j<m && flag;j++)
        {
            if (a[i][j] == 'C')
                for (int d = 0; d < 4 && flag; d++)
                    for (int x = i, y = j; flag && checkIn(x, y) && a[x][y] != 'W'; x += dir[d][0], y += dir[d][1])
                    {
                        if (a[x][y] == '.')
                            ans[x][y] = -2;
                        if (a[x][y] == 'S')
                            flag = false;
                    }
        }
    if(!flag)
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                ans[i][j]=-1;
    else
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(a[i][j]=='S')
                {
                    bfs(i, j);
                    break;
                }
}

void output()
{
    for(int i=0;i<n;i++)
        for(int j=0;j<m;j++)
            if(a[i][j]=='.')
                printf("%d\n",ans[i][j]<0?-1:ans[i][j]);
}

int main()
{
    input();
    solve();
    output();
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章