Cod sursa(job #1993888)

Utilizator mircea_marian.popaPopa Mircea-Marian mircea_marian.popa Data 23 iunie 2017 22:42:44
Problema Barbar Scor 80
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.81 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, a;
    queue < pair< unsigned short, unsigned short > > coordQ;
    for(i = 0 ; i < R ; i++)
        for(j = 0 ; j < C ; j++){
        	*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;
    j = R > C ? R : C;
    i = 1;
    while(i <= j) 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){
	    	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;
    }

    ofstream ofs ("barbar.out");
    ofs << dim;
    ofs.close();
    return 0;
}