Pagini recente » Cod sursa (job #235625) | Cod sursa (job #520659) | Cod sursa (job #2062439) | Cod sursa (job #2162355) | Cod sursa (job #2452555)
#include <iostream>
#include <fstream>
#include <vector>
#include <map>
std::ifstream fin("barbar.in");
std::ofstream fout("barbar.out");
int noLines, noColumns;
std::vector<std::vector<char>> dungeonMap;
std::vector<std::pair<int, int>> dragons;
std::pair<int, int> entrance;
std::pair<int, int> exit2;
std::vector<std::vector<int>> dragonDistMap;
std::vector<std::vector<int>> maxPassDistance;
#define x first
#define y second
#define DEBUG 0
#define PRINT(x) if(DEBUG) std::cout<<x<<'\n';
std::string to_string(std::pair<int, int> p) {
return std::string() + "(" + std::to_string(p.x) + ", " + std::to_string(p.y) + ")";
}
std::string to_string(std::vector<std::pair<int, int>> v) {
std::string s;
s.append("[");
for (int i = 0; i < v.size() - 1; i++)
s.append(to_string(v[i]) + ", ");
s.append(to_string(v[v.size() -1]) + "]");
return s;
}
bool descending(int a, int b) {
return a > b;
}
void solveTrail();
void populateDragonDistMap();
int main() {
fin>>noLines>>noColumns;
dungeonMap.resize(noLines);
for (std::vector<char>& line : dungeonMap)
line.resize(noColumns);
for (int i = 0; i < noLines; i++)
for (int j = 0; j < noColumns; j++) {
char spot;
fin>>spot;
dungeonMap[i][j] = spot;
if (spot == 'D')
dragons.push_back(std::make_pair(i, j));
else if (spot == 'I')
entrance = std::make_pair(i, j);
else if (spot == 'O')
exit2 = std::make_pair(i, j);
}
populateDragonDistMap();
solveTrail();
fout<<maxPassDistance[exit2.x][exit2.y];
}
std::vector<std::pair<int, int>> getValidNeighbors(std::pair<int, int> c) {
std::vector<std::pair<int, int>> sol;
c.x--;
if (c.x >= 0) sol.push_back(c);
c.x+= 2;
if (c.x < noLines) sol.push_back(c);
c.x--;
c.y--;
if (c.y >= 0) sol.push_back(c);
c.y+= 2;
if (c.y < noColumns) sol.push_back(c);
PRINT("Neighbors detected: " + to_string(sol));
return sol;
}
std::vector<std::pair<int, int>> getValidOpenNeighbors(std::pair<int, int> c) {
std::vector<std::pair<int, int>> sol;
c.x--;
if (c.x >= 0 && dungeonMap[c.x][c.y] != '*') sol.push_back(c);
c.x+= 2;
if (c.x < noLines && dungeonMap[c.x][c.y] != '*') sol.push_back(c);
c.x--;
c.y--;
if (c.y >= 0 && dungeonMap[c.x][c.y] != '*') sol.push_back(c);
c.y+= 2;
if (c.y < noColumns && dungeonMap[c.x][c.y] != '*') sol.push_back(c);
PRINT("Neighbors detected: " + to_string(sol));
return sol;
}
void solveTrail() {
PRINT("Entering solve trail");
//init maxPassDistance
maxPassDistance.resize(noLines);
for (std::vector<int>& line : maxPassDistance)
line.resize(noColumns, -1);
//insert first elem
std::multimap<int, std::pair<int, int>, bool(*) (int, int)> expandQueue(descending);
maxPassDistance[entrance.x][entrance.y] = dragonDistMap[entrance.x][entrance.y];
expandQueue.insert(std::make_pair(dragonDistMap[entrance.x][entrance.y], entrance));
bool foundExit = false;
while (!expandQueue.empty() && !foundExit) {
std::multimap<int, std::pair<int, int>>::iterator it = expandQueue.begin();
std::pair<int, int> currentSpot = it->second;
int currentDist = it->first;
expandQueue.erase(it);
PRINT("Exapanding "<<currentSpot.x<<' ' <<currentSpot.y)
std::vector<std::pair<int, int>> neighbors = getValidOpenNeighbors(currentSpot);
for (std::pair<int, int> n : neighbors)
if (maxPassDistance[n.x][n.y] == -1) {
maxPassDistance[n.x][n.y] = std::min(currentDist, dragonDistMap[n.x][n.y]);
expandQueue.insert(std::make_pair(maxPassDistance[n.x][n.y], n));
if (n == exit2) {
foundExit = true;
break;
}
}
}
}
void populateDragonDistMap() {
PRINT("Entering dragon populate map");
//init dragonDistMap
dragonDistMap.resize(noLines);
for (std::vector<int>& line : dragonDistMap)
line.resize(noColumns, -1);
//add first elements, the dragons
std::multimap<int, std::pair<int, int>> expandQueue;
for (std::pair<int, int> d : dragons) {
dragonDistMap[d.x][d.y] = 0;
expandQueue.insert(std::make_pair(0, d));
}
while (!expandQueue.empty()) {
std::multimap<int, std::pair<int, int>>::iterator it = expandQueue.begin();
std::pair<int, int> currentSpot = it->second;
int currentDist = it->first;
expandQueue.erase(it);
PRINT("Exapanding "<<currentSpot.x<<' ' <<currentSpot.y<<" -> "<<currentDist)
std::vector<std::pair<int, int>> neighbors = getValidNeighbors(currentSpot);
for (std::pair<int, int> n : neighbors)
if (dragonDistMap[n.x][n.y] == -1) {
PRINT("Adding "<<n.x<<' ' <<n.y<<" -> "<<currentDist + 1<<" to queue")
dragonDistMap[n.x][n.y] = currentDist + 1;
expandQueue.insert(std::make_pair(currentDist + 1, n));
}
}
}