반응형
문제 : https://www.acmicpc.net/problem/15685
서론
시뮬레이션 문제.
문제 의도는 파악하지 못했으나 일단은 규칙성을 찾아서 해결
아이디어
보통 회전이란 단어가 나오면 규칙성부터 찾아본다. 경험상 규칙을 찾을 수 있는 경우가 많다.
이 문제는 이동방향에 규칙이 있는데, 문제의 그림에서 규칙성을 찾아보기 위해 이동방향을 순서대로 나열한다.
0세대 : 0 ( 0방향으로 한칸 이동 )
1세대 : 0, 1 ( 0방향으로 이동 후 1방향으로 이동 )
2세대 : 0, 1, 2, 1
3세대 : 0, 1, 2, 1, 2, 3, 2, 1
4세대 : 0, 1, 2, 1, 2, 3, 2, 1, 2, 3, 0, 3, 2, 3, 2, 1
이제 규칙성을 찾을 수 있는데,
3세대 0, 1, 2, 1, 2, 3, 2, 1을 절반으로 나눴을때 앞부분 0, 1, 2, 1은 2세대와 같다.
그리고 뒷부분 2, 3, 2, 1을 또 절반으로 나눠서
나눈것의 앞부분 2, 3은 2세대 앞 절반의 0, 1을 각각 +2%4 한것과 같고( (0+2)%4 = 2, (1+2)%4 = 3 )
나눈것의 뒷부분 2, 1은 2세대 뒤 절반의 2, 1과 같다.
이렇게 이전세대로부터 다음세대의 방향을 예측할 수 있고, 이 규칙성은 0->1세대는 해당되지 않는다. 그래서 0->1세대만 예외처리해주는데, 0-> 1세대의 규칙성은
1세대의 앞부분 0은 0세대와 같고 뒷부분 1은 0세대에서 +1 이다.
구현
// c++
#include <vector>
#include <iostream>
int map[101][101];
int dy[4] = { 0, -1, 0, 1 };
int dx[4] = { 1, 0, -1, 0 };
void dragon(int x, int y, int d, int g) {
std::vector<int>v;
int cur = 0;
v.push_back(d);
while (cur++ < g) {
if (cur == 1) v.push_back((d + 1) % 4);
else {
for (int i = 0, size = v.size(); i < size ; i++) {
if (i < size / 2) v.push_back((v[i] + 2) % 4);
else v.push_back(v[i]);
}
}
}
map[y][x] = 1;
for (int i = 0, size = v.size(); i < size; i++) {
y = y + dy[v[i]];
x = x + dx[v[i]];
map[y][x] = 1;
}
}
int main() {
int n;
std::cin >> n;
while (n--) {
int x, y, d, g;
std::cin >> x >> y >> d >> g;
dragon(x, y, d, g);
}
int result = 0;
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 100; j++) {
if (map[i][j] == 1 && map[i + 1][j + 1] == 1 && map[i + 1][j] == 1 && map[i][j + 1] == 1) result++;
}
}
std::cout << result;
}
최근댓글