Cod sursa(job #1680035)

Utilizator depevladVlad Dumitru-Popescu depevlad Data 8 aprilie 2016 14:37:18
Problema Portal3 Scor 100
Compilator cpp Status done
Runda Arhiva de probleme Marime 2.95 kb
#include <fstream>
#include <vector>
#include <array>
#include <algorithm>

using namespace std;

ifstream in("portal3.in");
ofstream out("portal3.out");

class Point {
public:
   int x;
   int y;

   Point(int _x = 0, int _y = 0) :
      x(_x), y(_y) {}
};

class Portal {
public:
   Point first;
   Point second;
   int cost;
   bool isFlipped;

   Portal(Point _first = Point(), Point _second = Point(), int _cost = 0, bool _isFlipped = 0) :
      first(_first), second(_second), cost(_cost), isFlipped(_isFlipped) {}
};

int n, m;
long long bestAns;
array<Portal, 3> portList;
array<bool, 3> vis;

int distPoint(Point A, Point B) {
   return abs(A.x - B.x) + abs(A.y - B.y);
}

long long distPortal(Portal A, Portal B) {
   long long cost = A.cost;
   if(A.isFlipped) {
      if(B.isFlipped) cost += distPoint(A.first, B.second);
      else cost += distPoint(A.first, B.first);
   }
   else {
      if(B.isFlipped) cost += distPoint(A.second, B.second);
      else cost += distPoint(A.second, B.first);
   }
   return cost;
}

long long getPathLength(const vector<Portal> &path) {
   if(path.empty()) {
      return distPoint(Point(0, 0), Point(n, m));
   }
   long long length;
   if(path.front().isFlipped) length = distPoint(Point(0, 0), path.front().second);
   else length = distPoint(Point(0, 0), path.front().first);
   for(int i = 0; i < path.size() - 1; i++) {
      length += distPortal(path[i], path[i + 1]);
   }
   length += path.back().cost;
   if(path.back().isFlipped) length += distPoint(path.back().first, Point(n, m));
   else length += distPoint(path.back().second, Point(n, m));
   return length;
}

long long testAllConfigurations(vector<Portal> &path) {
   int nPort = path.size();
   long long partialBest = 0x7fffffffffffffff;
   for(int i = 0; i < (1 << nPort); i++) {
      for(int j = 0; j < nPort; j++) {
         if(i & (1 << j)) {
            path[j].isFlipped = 1;
         }
         else {
            path[j].isFlipped = 0;
         }
      }
      partialBest = min(partialBest, getPathLength(path));
   }
   return partialBest;
}

void backtracking(vector<Portal> &path) {
   bestAns = min(bestAns, testAllConfigurations(path));
   for(int i = 0; i < 3; i++) {
      if(!vis[i]) {
         path.push_back(portList[i]);
         vis[i] = 1;
         backtracking(path);
         vis[i] = 0;
         path.pop_back();
      }
   }
}

int main() {
   int testCase, x, y, c;
   vector<Portal> path;

   in >> testCase;
   while(testCase--) {
      in >> n >> m;
      for(int i = 0; i < 3; i++) {
         in >> x >> y;
         portList[i].first = Point(x, y);
         in >> x >> y;
         portList[i].second = Point(x, y);
         in >> c;
         portList[i].cost = c;
      }
      fill(vis.begin(), vis.end(), 0);
      bestAns = 0x7fffffffffffffff;
      path.clear();
      backtracking(path);
      out << bestAns << '\n';
   }

   return 0;
}