Cod sursa(job #2836141)

Utilizator lolismekAlex Jerpelea lolismek Data 19 ianuarie 2022 20:12:44
Problema Barbar Scor 0
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 4.93 kb
/*
#include <iostream>
#include <fstream>
#include <queue>

#define pii pair <int, int>
#define LIBER 0
#define PERETE 1
#define DRAGON 2

using namespace std;

ifstream fin("barbar.in");
ofstream fout("barbar.out");

const int N = 1000;
int original[N + 1][N + 1], harta[N + 1][N + 1], n, m;
bool reach[N + 1][N + 1];

/// ordine N, E, S, V:
int diri[] = {-1, 0, 1, 0};
int dirj[] = {0, 1, 0, -1};

void clear_harta(){
    for(int i = 1; i <= N; i++)
        for(int j = 1; j <= N; j++)
            reach[i][j] = harta[i][j] = 0;
}

bool in_bounds(int i, int j){
    return (1 <= i && i <= n && 1 <= j && j <= m);
}

void my_fill(pii nod){
    reach[nod.first][nod.second] = true;
    for(int dir = 0; dir < 4; dir++){
        if(!reach[nod.first + diri[dir]][nod.second + dirj[dir]] && harta[nod.first + diri[dir]][nod.second + dirj[dir]] == LIBER && in_bounds(nod.first + diri[dir], nod.second + dirj[dir]))
            my_fill({nod.first + diri[dir] ,nod.second + dirj[dir]});
    }
}

int main(){
    pii intrare, iesire;
    fin >> n >> m;
    char ch;
    fin.get(ch); /// '\n'
    for(int i = 1; i <= n; i++){
        for(int j = 1; j <= m; j++){
            fin.get(ch);
            if(ch == 'I') intrare = {i, j};
            if(ch == 'O') iesire = {i, j};
            if(ch == 'D') original[i][j] = DRAGON;
            if(ch == '*') original[i][j] = PERETE;
        }
        fin.get(ch); /// '\n'
    }
    int st = 0, dr = N, ans = -1;
    while(st <= dr){
        clear_harta();
        int dist = (st + dr) / 2;
        for(int i = 1; i <= n; i++)
            for(int j = 1; j <= m; j++)
                harta[i][j] = original[i][j];
        for(int i = 1; i <= n; i++){
            for(int j = 1; j <= m; j++){
                if(original[i][j] == DRAGON){
                    for(int dir = 0; dir < 4; dir++){
                        int x = i, y = j;
                        for(int k = 0; k < dist; k++){
                            x += diri[dir];
                            y += dirj[dir];
                            if(in_bounds(x, y) && original[x][y] == LIBER) harta[x][y] = PERETE;
                            else break;
                        }
                    }
                }
            }
        }
        my_fill(intrare);

        if(reach[iesire.first][iesire.second]) ans = dist, st = dist + 1;
        else dr = dist - 1;
    }
    if(ans != -1) ans++;
    fout << ans;
    return 0;
}
**/

// eu iau 50p si n am chef de debug, scz

#include <stdio.h>
#include <string.h>
#define NMAX 2000
typedef struct
	{
	 int x,y;
	} coord;
int n,m;
int xi,yi,xf,yf;
int dx[]={0,-1,0,1,0},dy[]={0,0,1,0,-1};
char s[NMAX+1][NMAX+1];
int d[NMAX+1][NMAX+1];
coord coada[NMAX*NMAX+1];
char viz[NMAX+1][NMAX+1];
int plee(int dist)
{
 int p=0,q=0,i,xx,yy;
 memset(viz,0,sizeof(viz));
 coada[0].x=xi;
 coada[0].y=yi;
 viz[xi][yi]=1;
 while (p<=q)
       {
	xx=coada[p].x;
	yy=coada[p].y;
	for (i=1;i<=4;i++)
	    if (xx+dx[i]>=0 && yy+dy[i]>=0)
	    if (d[xx+dx[i]][yy+dy[i]]>=dist && s[xx+dx[i]][yy+dy[i]]!='*' && !viz[xx+dx[i]][yy+dy[i]])
	       {
		q++;
		coada[q].x=xx+dx[i];
		coada[q].y=yy+dy[i];
		viz[xx+dx[i]][yy+dy[i]]=1;
		if (xx+dx[i]==xf && yy+dy[i]==yf) return 1;
	       }
	p++;
       }
return 0;
}
int posiesit()
{
 int p=0,q=0,i,xx,yy;
 memset(viz,0,sizeof(viz));
 coada[0].x=xi;
 coada[0].y=yi;
 viz[xi][yi]=1;
 while (p<=q)
       {
	xx=coada[p].x;
	yy=coada[p].y;
	for (i=1;i<=4;i++)
	    if (xx+dx[i]>=0 && yy+dy[i]>=0 && xx+dx[i]<n && yy+dy[i]<m)
	    if (s[xx+dx[i]][yy+dy[i]]!='*' && !viz[xx+dx[i]][yy+dy[i]])
	       {
		q++;
		coada[q].x=xx+dx[i];
		coada[q].y=yy+dy[i];
		viz[xx+dx[i]][yy+dy[i]]=1;
		if (xx+dx[i]==xf && yy+dy[i]==yf) return 1;
	       }
	p++;
       }
return 0;
}
int main()
{
 int i,j,q=-1,xx,yy,p;
 freopen("barbar.in","r",stdin);
 freopen("barbar.out","w",stdout);
 scanf("%d %d",&n,&m);
 gets(s[0]);
 for (i=0;i<n;i++)
     gets(s[i]);
 for (i=0;i<=n;i++)
  for (j=0;j<=m;j++) d[i][j]=32000;
 for (i=0;i<=m;i++) d[n][i]=32001;
 for (j=0;j<=n;j++) d[j][m]=32001;
 for (i=0;i<n;i++)
  for (j=0;j<m;j++)
      {
       if (s[i][j]=='I') xi=i, yi=j;
       if (s[i][j]=='D') coada[++q].x=i, coada[q].y=j, d[i][j]=0;
       if (s[i][j]=='O') xf=i, yf=j;
      }
 p=0;
 while (p<=q)
       {
	xx=coada[p].x;
	yy=coada[p].y;
	for (i=1;i<=4;i++)
	    if (xx+dx[i]>=0 && yy+dy[i]>=0)
	    if (d[xx+dx[i]][yy+dy[i]]==32000 && s[xx+dx[i]][yy+dy[i]]!='*')
	       {
		q++;
		coada[q].x=xx+dx[i];
		coada[q].y=yy+dy[i];
		d[xx+dx[i]][yy+dy[i]]=d[xx][yy]+1;
	       }
	p++;
       }
 int dmax=d[xi][yi];
 long step,dist=0;
 for (step=1; step<=dmax ; step<<=1);
 step<<=1;


 if (!posiesit()) printf("-1\n");
 else
 {
 for ( ; step>0; step>>=1)
  if (dist+step<=dmax)
     if (plee(dist+step)) dist+=step;


 printf("%d\n",dist);
 }
fclose(stdin);
fclose(stdout);
return 0;
}