Submission #226570

#TimeUsernameProblemLanguageResultExecution timeMemory
226570MKopchevPortals (BOI14_portals)C++14
100 / 100
326 ms23224 KiB
#include<bits/stdc++.h>
using namespace std;
const int nmax=1e3+42;

int n,m;

char inp[nmax][nmax];

char get_in()
{
    char c=getchar();
    while(c!='.'&&c!='#'&&c!='S'&&c!='C')c=getchar();
    return c;
}

bool in(int i,int j)
{
    return 1<=i&&i<=n&&1<=j&&j<=m;
}
int nxt_left[nmax][nmax],nxt_right[nmax][nmax],nxt_up[nmax][nmax],nxt_down[nmax][nmax];

int dist[nmax][nmax];

priority_queue< pair<int, pair<int,int> > > pq;

int x_move[4]={1,-1,0,0};
int y_move[4]={0,0,1,-1};

int calc_dist(pair<int,int> a,pair<int,int> b)
{
    return abs(a.first-b.first)+abs(a.second-b.second);
}
int main()
{
    scanf("%i%i",&n,&m);

    for(int i=0;i<=n+1;i++)
        for(int j=0;j<=m+1;j++)
        {
            if(in(i,j)==0)inp[i][j]='#';
            else inp[i][j]=get_in();
        }

    for(int i=0;i<=n+1;i++)
        for(int j=0;j<=m+1;j++)
        {
            if(inp[i][j]=='#')nxt_left[i][j]=j;
            else nxt_left[i][j]=nxt_left[i][j-1];

            if(inp[i][j]=='#')nxt_up[i][j]=i;
            else nxt_up[i][j]=nxt_up[i-1][j];
        }

    for(int i=n+1;i>=0;i--)
        for(int j=m+1;j>=0;j--)
        {
            if(inp[i][j]=='#')nxt_right[i][j]=j;
            else nxt_right[i][j]=nxt_right[i][j+1];

            if(inp[i][j]=='#')nxt_down[i][j]=i;
            else nxt_down[i][j]=nxt_down[i+1][j];
        }
    /*
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            cout<<i<<" "<<j<<" -> "<<nxt_left[i][j]<<" "<<nxt_right[i][j]<<" "<<nxt_down[i][j]<<" "<<nxt_up[i][j]<<endl;
        }
    */


    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            dist[i][j]=1e9;

    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
            if(inp[i][j]=='S')
            {
                pq.push({0,{i,j}});
                dist[i][j]=0;
            }

    while(pq.size())
    {
        pair<int, pair<int,int> > tp=pq.top();

        pq.pop();

        int d_now=-tp.first;

        int x=tp.second.first;
        int y=tp.second.second;

        if(dist[x][y]!=d_now)continue;

        if(in(x,y)==0)continue;

        //cout<<x<<" "<<y<<" -> "<<d_now<<endl;

        dist[x][y]=d_now;

        if(inp[x][y]=='C')
        {
            printf("%i\n",d_now);
            return 0;
        }

        if(inp[x][y]=='#')continue;

        //move adjacent
        for(int t=0;t<4;t++)
        {
            int x_=x+x_move[t];
            int y_=y+y_move[t];

            if(in(x_,y_))
            {
                if(dist[x_][y_]<=d_now+1)continue;

                pq.push({-(d_now+1),{x_,y_}});
                dist[x_][y_]=d_now+1;
            }
        }

        //use portals
        pair<int,int> go[4];

        go[0]={x,nxt_left[x][y]+1};
        go[1]={x,nxt_right[x][y]-1};
        go[2]={nxt_up[x][y]+1,y};
        go[3]={nxt_down[x][y]-1,y};

        for(int move_2=0;move_2<=3;move_2++)
        {
            //move (i,j) -> move_1 -> ( teleport ) move_2
            int lowest=1e9;

            for(int move_1=0;move_1<=3;move_1++)
                lowest=min(lowest,calc_dist({x,y},go[move_1])+1);

            if(dist[go[move_2].first][go[move_2].second]<=d_now+lowest)continue;

            pq.push({-(d_now+lowest),go[move_2]});

            dist[go[move_2].first][go[move_2].second]=d_now+lowest;
        }

    }

    assert(0==1);
    return 0;
}

Compilation message (stderr)

portals.cpp: In function 'int main()':
portals.cpp:35:10: warning: ignoring return value of 'int scanf(const char*, ...)', declared with attribute warn_unused_result [-Wunused-result]
     scanf("%i%i",&n,&m);
     ~~~~~^~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...