답안 #832555

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
832555 2023-08-21T11:39:22 Z 79brue Sky Walking (IOI19_walk) C++17
33 / 100
793 ms 142028 KB
#include "walk.h"
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

struct Edge{
	int l, r, y, idx;
	Edge(){}
	Edge(int l, int r, int y, int idx): l(l), r(r), y(y), idx(idx){}
	bool operator<(const Edge &r)const{
		if(y != r.y) return y < r.y;
		return idx < r.idx;
	}
};

int n, k, Start, Goal;
ll arr[100002];
ll height[100002];
ll el[100002], er[100002], ey[100002];

void findIntersections();
ll solve();

ll min_distance(vector<int> _x, vector<int> _h, vector<int> _l, vector<int> _r,
			    vector<int> _y, int _s, int _t) {
	n = (int)_x.size();
	for(int i=1; i<=n; i++) arr[i] = _x[i-1], height[i] = _h[i-1];
	k = (int)_l.size();

	vector<Edge> vec;
	for(int i=1; i<=k; i++) vec.push_back(Edge(_l[i-1] + 1, _r[i-1] + 1, _y[i-1], i));
	sort(vec.begin(), vec.end());
	
	for(int i=1; i<=k; i++) el[i] = vec[i-1].l, er[i] = vec[i-1].r, ey[i] = vec[i-1].y;
	
	Start = _s+1, Goal = _t+1;

	findIntersections();
	return solve();
}

/// 정점과 간선 정보
int floorV[100002];
vector<pair<int, ll> > link[2000002];
vector<int> addLine[100002], delLine[100002];

vector<pair<int, int> > edgeIdx[100002]; /// 간선별로 정점을 추가할 x좌표들, 그리고 그 정점 번호
vector<pair<int, int> > towerIdx[100002]; /// x좌표별로 정점을 추가할 높이들, 그리고 그 정점 번호
int recent[100002];

void findIntersections(){
	for(int i=1; i<=k; i++){
		addLine[el[i]].push_back(i);
		delLine[er[i]].push_back(i);
	}

	/// Subtask 4의 정점들만 추가
	int vCnt = 0;
	set<int> st; /// 간선 번호
	for(int i=1; i<=n; i++){
		for(int x: addLine[i]){
			// printf("addLine %d - %d\n", i, x);
			edgeIdx[x].push_back(make_pair(arr[i], ++vCnt));
			towerIdx[i].push_back(make_pair(ey[x], vCnt));
			// printf("%d: (%d, %d)\n", vCnt, arr[i], ey[x]);
			recent[x] = i;

			auto it = st.insert(x).first;
			if(it != st.begin() && recent[*prev(it)] != i){
				int y = *prev(it);
				edgeIdx[y].push_back(make_pair(arr[i], ++vCnt));
				towerIdx[i].push_back(make_pair(ey[y], vCnt));
				// printf("%d: (%d, %d)\n", vCnt, arr[i], ey[y]);
				recent[y] = i;
			}
			if(next(it) != st.end() && recent[*next(it)] != i){
				int y = *next(it);
				edgeIdx[y].push_back(make_pair(arr[i], ++vCnt));
				towerIdx[i].push_back(make_pair(ey[y], vCnt));
				// printf("%d: (%d, %d)\n", vCnt, arr[i], ey[y]);
				recent[y] = i;
			}
		}
		for(int x: delLine[i]){
			// printf("delLine %d - %d\n", i, x);
			edgeIdx[x].push_back(make_pair(arr[i], ++vCnt));
			towerIdx[i].push_back(make_pair(ey[x], vCnt));
			// printf("%d: (%d, %d)\n", vCnt, arr[i], ey[x]);
			recent[x] = i;

			auto it = st.find(x);
			if(it != st.begin() && recent[*prev(it)] != i && arr[*prev(it)] <= ey[i]){
				int y = *prev(it);
				edgeIdx[y].push_back(make_pair(arr[i], ++vCnt));
				towerIdx[i].push_back(make_pair(ey[y], vCnt));
				// printf("%d: (%d, %d)\n", vCnt, arr[i], ey[y]);
				recent[y] = i;
			}
			if(next(it) != st.end() && recent[*next(it)] != i && arr[*next(it)] <= ey[i]){
				int y = *next(it);
				edgeIdx[y].push_back(make_pair(arr[i], ++vCnt));
				towerIdx[i].push_back(make_pair(ey[y], vCnt));
				// printf("%d: (%d, %d)\n", vCnt, arr[i], ey[y]);
				recent[y] = i;
			}
			st.erase(x);
		}
		towerIdx[i].push_back(make_pair(0, ++vCnt));
		floorV[i] = vCnt;
		// printf("%d: (%d, %d)\n", vCnt, arr[i], 0);
	}

	/// Full task의 정점들도 추가
	/// ...

	/// 정점들을 간선으로 연결
	for(int i=1; i<=k; i++){
		sort(edgeIdx[i].begin(), edgeIdx[i].end());
		for(int j=0; j<(int)edgeIdx[i].size()-1; j++){
			int x = edgeIdx[i][j].second, y = edgeIdx[i][j+1].second;
			int v = edgeIdx[i][j+1].first - edgeIdx[i][j].first;
			// printf("Connect %d %d : %d\n", x, y, v);
			link[x].push_back(make_pair(y, v));
			link[y].push_back(make_pair(x, v));
		}
	}

	for(int i=1; i<=n; i++){
		sort(towerIdx[i].begin(), towerIdx[i].end());
		for(int j=0; j<(int)towerIdx[i].size()-1; j++){
			int x = towerIdx[i][j].second, y = towerIdx[i][j+1].second;
			int v = towerIdx[i][j+1].first - towerIdx[i][j].first;
			// printf("Connect %d %d : %d\n", x, y, v);
			link[x].push_back(make_pair(y, v));
			link[y].push_back(make_pair(x, v));
		}
	}
}

struct dat{
	int x; ll d;
	dat(){}
	dat(int x, ll d): x(x), d(d){}
	bool operator<(const dat &r)const{
		return d>r.d;
	}
};
bool visited[2000002];

ll solve(){
	// printf("Solve %d to %d\n", floorV[Start], floorV[Goal]);
	priority_queue<dat> pq;
	pq.push(dat(floorV[Start], 0));
	while(!pq.empty()){
		dat tmp = pq.top(); pq.pop();
		if(visited[tmp.x]) continue;
		if(tmp.x == floorV[Goal]) return tmp.d;
		visited[tmp.x] = 1;

		for(pair<int, ll> p: link[tmp.x]){
			pq.push(dat(p.first, tmp.d + p.second));
		}
	}
	// printf("No solution\n");
	return -1;
}
# 결과 실행 시간 메모리 Grader output
1 Incorrect 27 ms 56612 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Incorrect 27 ms 56644 KB Output isn't correct
2 Halted 0 ms 0 KB -
# 결과 실행 시간 메모리 Grader output
1 Correct 116 ms 79136 KB Output is correct
2 Correct 477 ms 130780 KB Output is correct
3 Correct 580 ms 132968 KB Output is correct
4 Correct 589 ms 134772 KB Output is correct
5 Correct 793 ms 142028 KB Output is correct
6 Correct 635 ms 141496 KB Output is correct
7 Correct 312 ms 99776 KB Output is correct
8 Correct 241 ms 113480 KB Output is correct
9 Correct 634 ms 135104 KB Output is correct
10 Correct 293 ms 116552 KB Output is correct
11 Correct 38 ms 60756 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Correct 116 ms 79136 KB Output is correct
2 Correct 477 ms 130780 KB Output is correct
3 Correct 580 ms 132968 KB Output is correct
4 Correct 589 ms 134772 KB Output is correct
5 Correct 793 ms 142028 KB Output is correct
6 Correct 635 ms 141496 KB Output is correct
7 Correct 312 ms 99776 KB Output is correct
8 Correct 241 ms 113480 KB Output is correct
9 Correct 634 ms 135104 KB Output is correct
10 Correct 293 ms 116552 KB Output is correct
11 Correct 38 ms 60756 KB Output is correct
12 Correct 606 ms 133144 KB Output is correct
13 Correct 406 ms 127964 KB Output is correct
14 Correct 657 ms 135556 KB Output is correct
15 Correct 526 ms 126560 KB Output is correct
16 Correct 525 ms 126720 KB Output is correct
17 Correct 686 ms 133176 KB Output is correct
18 Correct 550 ms 126516 KB Output is correct
19 Correct 623 ms 126716 KB Output is correct
20 Correct 296 ms 98400 KB Output is correct
21 Correct 53 ms 66016 KB Output is correct
22 Correct 506 ms 118024 KB Output is correct
23 Correct 481 ms 117252 KB Output is correct
24 Correct 431 ms 113720 KB Output is correct
25 Correct 432 ms 114044 KB Output is correct
26 Correct 393 ms 118264 KB Output is correct
27 Correct 742 ms 136532 KB Output is correct
28 Correct 360 ms 127984 KB Output is correct
29 Correct 585 ms 132668 KB Output is correct
30 Correct 271 ms 98548 KB Output is correct
31 Correct 581 ms 135228 KB Output is correct
32 Correct 256 ms 113288 KB Output is correct
33 Correct 316 ms 120240 KB Output is correct
34 Correct 303 ms 121632 KB Output is correct
35 Correct 366 ms 124084 KB Output is correct
36 Correct 262 ms 115416 KB Output is correct
37 Correct 269 ms 112256 KB Output is correct
38 Correct 354 ms 125784 KB Output is correct
39 Correct 345 ms 134908 KB Output is correct
40 Correct 302 ms 123696 KB Output is correct
41 Correct 272 ms 114568 KB Output is correct
# 결과 실행 시간 메모리 Grader output
1 Incorrect 27 ms 56612 KB Output isn't correct
2 Halted 0 ms 0 KB -