Posts 10875 뱀
Post
Cancel

10875 뱀

알고리즘

  • 뱀이 성장하면서 생기는 가로직선, 세로직선을 따로 저장.
  • 새롭게 생기는 직선이 이전에 저장된 직선에 걸리는지 확인.
  • 이때, 직선은 정렬하여 뱀이 나아가는 방향에서 가장 가까운 직선에 걸리도록 하자.

여담

  • 깔끔하게 구현하기에 매우 애를 먹었고, 가능하지도 않았다. 그만큼 분리하여 생각해야하는 조건들이 많고, 그렇기에 실수를 할 가능성이 매우 크다.
  • 알고리즘 자체를 간단하므로, 틀렸습니다가 뜬다면 실수를 하지 않았는지를 중점으로 찾아보면 될 것 같다.

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include <iostream>
#include <set>

typedef long long LL;

using namespace std;

set<pair<LL, pair<LL, LL>>> v, h;
LL l, n, ans, curDir = 1, cr, cc;

bool add(int, int);
bool check(LL, LL);

int main() {
	cin >> l >> n;

	pair<LL, pair<LL, LL>> t[3] = { { l + 1, {-l, l} },{ -l - 1, {-l, l} }, { 0,{0,0} } };
	for (int i = 0; i < 3; i++) {
		h.insert(t[i]);
		v.insert(t[i]);
	}

	int a;
	char b;
	bool check = false;
	while (n--) {
		cin >> a >> b;
		if (!add(a, b)) {
			check = true;
			break;
		}
	}

	if(!check)
		add(2000000010, 'L');

	cout << ans;
	return 0;
}

bool add(int t, int dir) {
	LL nr = curDir == 0 ? cr + t : cr - t, nc = curDir == 1 ? cc + t : cc - t;
	if (curDir % 2 == 0) {
		cr += curDir == 0 ? 1 : -1;
		if (!check(nr, cc))
			return false;

		curDir == 0 ? v.insert({ cc, {cr, nr} }) : v.insert({ cc, {nr, cr} });
		cr = nr;
	}
	else {
		cc += curDir == 1 ? 1 : -1;
		if (!check(cr, nc))
			return false;

		curDir == 1 ? h.insert({ cr, {cc, nc} }) : h.insert({ cr, {nc, cc} });
		cc = nc;
	}
	ans += t;

	if ((curDir == 1 && dir == 'L') || (curDir == 3 && dir =='R'))
		curDir = 0;
	else if ((curDir == 2 && dir == 'L') || (curDir == 0 && dir == 'R'))
		curDir = 1;
	else if ((curDir == 3 && dir == 'L') || (curDir == 1 && dir == 'R'))
		curDir = 2;
	else if ((curDir == 0 && dir == 'L') || (curDir == 2 && dir == 'R'))
		curDir = 3;
	return true;
}

bool check(LL nr, LL nc) {
	if (curDir % 2 == 0) {
		LL higher = curDir == 0 ? nr : cr, lower = curDir == 0 ? cr : nr;
		if (curDir == 0) {
			for (auto iter = h.begin(); iter != h.end(); iter++) {
				if (lower <= (*iter).first && higher >= (*iter).first && (*iter).second.first <= cc && (*iter).second.second >= cc) {
					ans += (*iter).first - lower + 1;
					return false;
				}
			}
		}
		else {
			auto iter = h.end();
			iter--;
			for (; iter != h.begin(); iter--) {
				if (lower <= (*iter).first && higher >= (*iter).first && (*iter).second.first <= cc && (*iter).second.second >= cc) {
					ans += higher - (*iter).first + 1;
					return false;
				}
			}
			if (lower <= (*iter).first && higher >= (*iter).first && (*iter).second.first <= cc && (*iter).second.second >= cc) {
				ans += higher - (*iter).first + 1;
				return false;
			}
		}
		for (auto iter = v.begin(); iter != v.end(); iter++) {
			int vc = (*iter).first, vlh = (*iter).second.first, vhh = (*iter).second.second;

			if (cc == vc && ((higher >= vlh && higher <= vhh) || (lower >= vlh && lower <= vhh) || (higher > vhh && lower < vlh))) {
				ans += curDir == 0 ? vlh - lower + 1 : higher - vhh + 1;
				return false;
			}
		}
	}
	else {
		LL higher = curDir == 1 ? nc : cc, lower = curDir == 1 ? cc : nc;
		if (curDir == 1) {
			for (auto iter = v.begin(); iter != v.end(); iter++)
				if (lower <= (*iter).first && higher >= (*iter).first && (*iter).second.first <= cr && (*iter).second.second >= cr) {
					ans += (*iter).first - lower + 1;
					return false;
				}
		}
		else {
			auto iter = v.end();
			iter--;
			for (; iter != v.begin(); iter--)
				if (lower <= (*iter).first && higher >= (*iter).first && (*iter).second.first <= cr && (*iter).second.second >= cr) {
					ans += higher - (*iter).first + 1;
					return false;
				}
			if (lower <= (*iter).first && higher >= (*iter).first && (*iter).second.first <= cc && (*iter).second.second >= cc) {
				ans += higher - (*iter).first + 1;
				return false;
			}
		}
		for (auto iter = h.begin(); iter != h.end(); iter++) {
			int hh = (*iter).first, hlc = (*iter).second.first, hhc = (*iter).second.second;

			if (cr == hh && ((higher >= hlc && higher <= hhc) || (lower >= hlc && lower <= hhc) || (higher > hhc && lower < hlc))) {
				ans += curDir == 1 ? hlc - lower + 1: higher - hhc + 1;
				return false;
			}
		}
	}
	return true;
}
This post is licensed under CC BY 4.0 by the author.

9874 Wormholes

브라우저 동작원리

Comments powered by Disqus.