Cod sursa(job #1997337)

Utilizator mihai.alphamihai craciun mihai.alpha Data 3 iulie 2017 22:46:33
Problema Barbar Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 3.68 kb
#include <iostream>
#include <fstream>
#include <utility>
#include <queue>
#include <limits.h>
#include <algorithm>
#include <cstring>
 
#define isValid(i, j) (\
    i < R && j < C && discovered[i][j] == false &&\
    map[i][j] != '*'\
)
using namespace std;
 
 
int main(){
    ifstream ifs ("barbar.in");
    unsigned short R, C, i, j, start_i = 0, start_j = 0,
        finish_i = 0, finish_j = 0;
    ifs >> R >> C;
    char map[R][C], *it_map = (char *)map;
    bool discovered[R][C], *it_discovered = (bool *)discovered;
    unsigned int closestDragon[R][C],
        *it_closestDragon = (unsigned int *)closestDragon;
    queue < pair< unsigned short, unsigned short > > coordQ;
    for(i = 0 ; i < R ; i++)
        for(j = 0 ; j < C ; j++){
            *it_closestDragon = 50;
            *it_discovered = false;
            ifs >> *it_map;
            if(*it_map == 'D'){
                coordQ.push(make_pair(i, j));
                *it_closestDragon = 0;
                *it_discovered = true;
            } else if (*it_map == 'I'){
                start_j = j;
                start_i = i;
            } else if(*it_map == 'O'){
                finish_j = j;
                finish_i = i;
            }
            it_map++;
            it_discovered++;
            it_closestDragon++;
        }
    ifs.close();
 
    const signed short dir_i[4] = {-1, 1, 0, 0},
        dir_j[4] = {0, 0, -1, 1};
    unsigned short next_i, next_j;
    pair<unsigned short, unsigned short> p;
    while(!coordQ.empty()){
        p = coordQ.front();
        coordQ.pop();
 
        for(i = 0 ; i < 4 ; i++){
            next_i = p.first + dir_i[i];
            next_j = p.second + dir_j[i];
            if(isValid(next_i, next_j)){
                coordQ.push(make_pair(next_i ,next_j));
                closestDragon[next_i][next_j] = closestDragon[p.first][p.second]
                    + 1;
                discovered[next_i][next_j] = true;
            }
        }
    }
 
    unsigned short dim = 0, it, newDim;
    bool foundPath, pathExists = false;
    j = R < C ? R : C;
    i = 1;
    while(i <= j) i <<= 1;
    i >>= 1;
    for(it = i ; it >= 1 ; it >>= 1){
        newDim = dim + it;
        foundPath = false;
        memset(discovered, 0, R * C * sizeof(bool));
 
        if(closestDragon[start_i][start_j] >= newDim &&
            closestDragon[finish_i][finish_j] >= newDim){
             
            coordQ.push(make_pair(start_i, start_j));
            discovered[start_i][start_j] = true;
             
            while(!coordQ.empty()){
                p = coordQ.front();
                coordQ.pop();
 
                for(i = 0 ; i < 4 ; i++){
                    next_i = p.first + dir_i[i];
                    next_j = p.second + dir_j[i];
                     
                    if(next_i == finish_i && next_j == finish_j){
                        queue < pair< unsigned short, unsigned short > > emptyQ;
                        swap(coordQ, emptyQ);
                        foundPath = true;
                        break;
                    }
 
                    if(isValid(next_i, next_j) && closestDragon[next_i][next_j] >= newDim){
                         
                        coordQ.push(make_pair(next_i ,next_j));
                        discovered[next_i][next_j] = true;
 
                    }
                }
            }
        }
        if(foundPath){
            dim = newDim;
            if(!pathExists)
                pathExists = true;
        }
    }
 
    ofstream ofs ("barbar.out");
    if(pathExists)
        ofs << dim;
    else
        ofs << -1;
    ofs.close();
    return 0;
}