problem G
unknown
c_cpp
7 months ago
12 kB
0
Indexable
Never
#include<bits/stdc++.h> using namespace std; typedef pair<int, int> pii; typedef long double ld; typedef long long ll; #define mp make_pair #define pb push_back #define in insert #define ers erase #define S second #define F first const int N = 1e2 + 5; const int inF = 1e9 + 7; int n, x[2 * N], y[2 * N], z[N], xCnt, yCnt, zCnt, dist[4 * N * N * N]; bool availablePoints[4 * N * N * N], vis[4 * N * N * N]; set<int> xPoints, yPoints, zPoints; int adj[4 * N * N * N][10]; set<pii> q; class point { public: int x, y, z; } stPoint, enPoint; class building { public: point westSouth, eastNorth; } buildings[N]; void read_input() { cin >> n; for (int i = 0; i < n; i++) { cin >> buildings[i].westSouth.x >> buildings[i].westSouth.y; cin >> buildings[i].eastNorth.x >> buildings[i].eastNorth.y; cin >> buildings[i].westSouth.z; buildings[i].eastNorth.z = buildings[i].westSouth.z; } cin >> stPoint.x >> stPoint.y >> stPoint.z; cin >> enPoint.x >> enPoint.y >> enPoint.z; } void sortPoints() { for (int i = 0; i < n; i++) { xPoints.in(buildings[i].westSouth.x); xPoints.in(buildings[i].eastNorth.x); yPoints.in(buildings[i].westSouth.y); yPoints.in(buildings[i].eastNorth.y); zPoints.in(buildings[i].westSouth.z); } xPoints.in(stPoint.x); xPoints.in(enPoint.x); yPoints.in(stPoint.y); yPoints.in(enPoint.y); zPoints.in(stPoint.z); zPoints.in(enPoint.z); zPoints.in(0); for (auto p : xPoints) { x[xCnt] = p; xCnt++; } for (auto p : yPoints) { y[yCnt] = p; yCnt++; } for (auto p : zPoints) { z[zCnt] = p; zCnt++; } } void debug() { /* cout << "********\n"; for (int i = 0; i < xCnt; i++) cout << x[i] << ' '; cout << '\n'; for (int i = 0; i < yCnt; i++) cout << y[i] << ' '; cout << '\n'; for (int i = 0; i < zCnt; i++) cout << z[i] << ' '; cout << "\n**********\n"; for (int i = 0; i < n; i++) cout << buildings[i].westSouth.x << ' ' << buildings[i].westSouth.y << ' '; cout << buildings[i].eastNorth.x << ' ' << buildings[i].eastNorth.y << ' '; cout << buildings[i].westSouth.z << '\n'; cout << "**********\n"; for (int iz = 0; iz < zCnt; iz++) { cout << "---z : " << iz << '\n'; for (int ix = 0; ix < xCnt; ix++) { for (int iy = 0; iy < yCnt; iy++) { int node = xCnt * yCnt * iz + yCnt * ix + iy; cout << availablePoints[node] << ' '; } cout << '\n'; } }*/ } int convertX(int xOfBuilding) { int l = 0, r = xCnt; while(r - l > 1) { int mid = (l + r) / 2; x[mid] > xOfBuilding? r = mid : l = mid; } return l; } int convertY(int yOfBuilding) { int l = 0, r = yCnt; while(r - l > 1) { int mid = (l + r) / 2; y[mid] > yOfBuilding? r = mid : l = mid; } return l; } int convertZ(int zOfBuilding) { int l = 0, r = zCnt; while(r - l > 1) { int mid = (l + r) / 2; z[mid] > zOfBuilding? r = mid : l = mid; } return l; } void convertPoints() { for (int i = 0; i < n; i++) { buildings[i].westSouth.x = convertX(buildings[i].westSouth.x); buildings[i].eastNorth.x = convertX(buildings[i].eastNorth.x); buildings[i].westSouth.y = convertY(buildings[i].westSouth.y); buildings[i].eastNorth.y = convertY(buildings[i].eastNorth.y); buildings[i].westSouth.z = convertZ(buildings[i].westSouth.z); buildings[i].eastNorth.z = buildings[i].westSouth.z; } stPoint.x = convertX(stPoint.x); enPoint.x = convertX(enPoint.x); stPoint.y = convertY(stPoint.y); enPoint.y = convertY(enPoint.y); stPoint.z = convertZ(stPoint.z); enPoint.z = convertZ(enPoint.z); } void determineAvailablePoints() { memset(availablePoints, 1, sizeof (availablePoints)); for (int i = 0; i < n; i++) { int x1 = buildings[i].westSouth.x, x2 = buildings[i].eastNorth.x; int y1 = buildings[i].westSouth.y, y2 = buildings[i].eastNorth.y; int z1 = buildings[i].westSouth.z; for (int ix = x1 + 1; ix < x2; ix++) for (int iy = y1 + 1; iy < y2; iy++) for (int iz = 0; iz < z1; iz++) { int node = xCnt * yCnt * iz + yCnt * ix + iy; availablePoints[node] = 0; } } } void makeEdge() { memset(adj, inF, sizeof (adj)); for (int ix = 0; ix < xCnt; ix++) for (int iy = 0; iy < yCnt; iy++) for (int iz = 0; iz < zCnt; iz++) { int node = xCnt * yCnt * iz + yCnt * ix + iy; if (availablePoints[node]) { if (iz > 0) if (availablePoints[node - xCnt * yCnt]) { adj[node][0] = z[iz] - z[iz - 1]; } else adj[node][0] = inF; if (iz < zCnt - 1) if (availablePoints[node + xCnt * yCnt]) { adj[node][1] = z[iz + 1] - z[iz]; } else adj[node][1] = inF; if (ix > 0) if (availablePoints[node - yCnt]) { adj[node][2] = x[ix] - x[ix - 1]; } else adj[node][2] = inF; if (ix < xCnt - 1) if (availablePoints[node + yCnt]) { adj[node][3] = x[ix + 1] - x[ix]; } else adj[node][3] = inF; if (iy > 0) if (availablePoints[node - 1]) { adj[node][4] = y[iy] - y[iy - 1]; } else adj[node][4] = inF; if (iy < yCnt - 1) if (availablePoints[node + 1]) { adj[node][5] = y[iy + 1] - y[iy]; } else adj[node][5] = inF; } else for (int i = 0; i < 6; i++) adj[node][i] = inF; } } void deleteEdge() { for (int i = 0; i < n; i++) { int x1 = buildings[i].westSouth.x, x2 = buildings[i].eastNorth.x; int y1 = buildings[i].westSouth.y, y2 = buildings[i].eastNorth.y; int z1 = buildings[i].westSouth.z; for (int ix = x1 + 1; ix <= x2 - 1; ix++) for (int iy = y1 + 1; iy <= y2 - 1; iy++) for (int iz = 1; iz <= z1 - 1; iz++) { int node = xCnt * yCnt * iz + yCnt * ix + iy; for (int i = 0; i < 6; i++) adj[node][i] = inF; } for (int ix = x1 + 1; ix <= x2 - 1; ix++) for (int iy = y1 + 1; iy <= y2 - 1; iy++) { int node = xCnt * yCnt * z1 + yCnt * ix + iy; adj[node][0] = inF; } for (int ix = x1 + 1; ix <= x2 - 1; ix++) for (int iy = y1 + 1; iy <= y2 - 1; iy++) { int node = xCnt * yCnt * 0 + yCnt * ix + iy; adj[node][1] = inF; } for (int iy = y1 + 1; iy <= y2 - 1; iy++) for (int iz = 0; iz <= z1 - 1; iz++) { int node = xCnt * yCnt * iz + yCnt * x2 + iy; adj[node][2] = inF; } for (int iy = y1 + 1; iy <= y2 - 1; iy++) for (int iz = 0; iz <= z1 - 1; iz++) { int node = xCnt * yCnt * iz + yCnt * x1 + iy; adj[node][3] = inF; } for (int ix = x1 + 1; ix <= x2 - 1; ix++) for (int iz = 0; iz <= z1 - 1; iz++) { int node = xCnt * yCnt * iz + yCnt * ix + y2; adj[node][4] = inF; } for (int ix = x1 + 1; ix <= x2 - 1; ix++) for (int iz = 0; iz <= z1 - 1; iz++) { int node = xCnt * yCnt * iz + yCnt * ix + y1; adj[node][5] = inF; } /* for (int ix = x1 + 1; ix <= x2 - 1; ix++) for (int iy = y1 + 1; iy <= y2 - 1; iy++) for (int iz = 1; iz <= z1 - 1; iz++) { int node = xCnt * yCnt * iz + yCnt * ix + iy; adj[node][2] = inF; adj[node - yCnt][3] = inF; } for (int ix = x1 + 1; ix <= x2 - 1; ix++) for (int iy = y1 + 1; iy <= y2 - 1; iy++) for (int iz = 1; iz <= z1 - 1; iz++) { int node = xCnt * yCnt * iz + yCnt * ix + iy; adj[node][4] = inF; adj[node - 1][5] = inF; }*/ } } void dijkstra() { int stNode = xCnt * yCnt * stPoint.z + yCnt * stPoint.x + stPoint.y; memset(dist, inF, sizeof (dist)); dist[stNode] = 0; q.in(pii(0, stNode)); while(!q.empty()) { //cout << "---------------\n"; set<pii> :: iterator it = q.begin(); int u = it->second; q.ers(it); vis[u] = true; //cout << x[(u % (xCnt * yCnt)) / yCnt] << ", " << y[(u % (xCnt * yCnt)) % yCnt] << ", " << z[u / (xCnt * yCnt)] << " : " << dist[u] << '\n'; int v = u - xCnt * yCnt; if (!vis[v]) if (dist[v] > dist[u] + adj[u][0]) { if (dist[v] < inF) q.ers(pii(dist[v], v)); dist[v] = dist[u] + adj[u][0]; q.in(pii(dist[v], v)); } v = u + xCnt * yCnt; if (!vis[v]) if (dist[v] > dist[u] + adj[u][1]) { if (dist[v] < inF) q.ers(pii(dist[v], v)); dist[v] = dist[u] + adj[u][1]; q.in(pii(dist[v], v)); } v = u - yCnt; if (!vis[v]) if (dist[v] > dist[u] + adj[u][2]) { if (dist[v] < inF) q.ers(pii(dist[v], v)); dist[v] = dist[u] + adj[u][2]; q.in(pii(dist[v], v)); } v = u + yCnt; if (!vis[v]) if (dist[v] > dist[u] + adj[u][3]) { if (dist[v] < inF) q.ers(pii(dist[v], v)); dist[v] = dist[u] + adj[u][3]; q.in(pii(dist[v], v)); } v = u - 1; if (!vis[v]) if (dist[v] > dist[u] + adj[u][4]) { if (dist[v] < inF) q.ers(pii(dist[v], v)); dist[v] = dist[u] + adj[u][4]; q.in(pii(dist[v], v)); } v = u + 1; if (!vis[v]) if (dist[v] > dist[u] + adj[u][5]) { if (dist[v] < inF) q.ers(pii(dist[v], v)); dist[v] = dist[u] + adj[u][5]; q.in(pii(dist[v], v)); } } } void solve() { sortPoints(); convertPoints(); determineAvailablePoints(); makeEdge(); deleteEdge(); dijkstra(); debug(); } void output() { int enNode = xCnt * yCnt * enPoint.z + yCnt * enPoint.x + enPoint.y; cout << dist[enNode] << '\n'; } int main() { read_input(); solve(); output(); return 0; }
Leave a Comment