Codetree. 놀이기구 탑승
1. 문제설명
n*n
격자에n*n
명의 학생을 탑승시키려고 한다.- 처음에 격자는 모든 칸이 비어있다.
- 각 학생별로 좋아하는 학생이 정확히 4명씩 정해져있다.
- 자기 자신을 좋아하는 학생은 없고, 동일한 학생의 번호가 2번 주어지는 경우도 없다.
- 아래의 우선순위 중 위에서부터 가장 먼저 만족하는 우선순위 순으로 탑승한다.
- 격자를 벗어나지 않는 4방향으로 인접한 칸 중 앉아있는 좋아하는 친구의 수가 가장 많은 위치
- 그 중 인접한 칸 중 비어있는 칸의 수가 가장 많은 위치
- 행 번호가 가장 작은 위치
- 열 번호가 가장 작은 위치
- 전부 탑승한 이후 각 학생마다의 점수를 합한 점수 출력
- 인접한 학생의 수에 따라
{0, 1, 10, 100, 1000}
점 부여
- 인접한 학생의 수에 따라
2. 입/출력
- 입력
- 격자의 크기를 나타내는
n
n * n
개의 줄에 걸쳐 각 학생의 정보n0, n1, n2, n3, n4
- 격자의 크기를 나타내는
- 출력
- 모든 학생들이 놀이기구에 탑승한 이후의 최종 점수 출력
3. 문제 분류
- Simulation
4. 알고리즘 설계
- 위치 탐색을 제외한 알고리즘은 간단하니 생략하겠다.
-
정보 저장을 위한 구조체, 배열은 다음과 같이 선언하였다.
struct student { int num; // 학생 번호 vector<int> likes; // 좋아하는 학생 4명 번호 }; int board[SZ][SZ]; // 격자의 정보 pair<int, int> pos[SZ * SZ]; // i번째 학생의 좌표 정보 vector<student> v; //
- 격자의 비어있는 칸을 전부 탐색하면서 인접한 4방향을 탐색한다.
- 탐색을 하면서 빈칸의 개수, 좋아하는 학생의 수를 카운팅
- 좋아하는 학생의 수, 비어있는 칸 수, x, y 순으로 저장해서 벡터에 쌓는다.
- 쌓여진 벡터는 다음 칸으로 이동할 수 있는 모든 칸이 된다.
- 우선순위에 따라 정렬하고 0번째의 벡터 원소를 통해 위치를 지정한다.
- 이 때,
pos
와board
에 대한 정보를 갱신한다.
- 이 때,
5. 전체 코드
6. 소감
tmp.push_back(make_tuple(~like, ~empty, i, j));
이 코드의 아이디어가 좋다고 생각한다.- 다른 언어는 모르겠지만 C++의 STL을 통해
sort()
함수를 사용하면 맨 앞에 원소부터 작은 순으로 정렬된다. - 이 문제에서는 좋아하는 학생 수, 비어있는 칸은 많을 수록 우선순위가 높고 x, y는 낮을수록 우선순위가 높다.
~
을 붙여 음수로 만들어주면 원래의 값이 클수록 음수에서는 작아지기 때문에 별도의compare
함수를 작성하지 않아도 된다.-
를 붙여도 될 거 같지만, 그렇게 하면 안된다.~
는 bit-wise NOT 연산자로 부호 비트를 포함한 비트를 모두 반전시킨다.-
는 단순히 값을 부정하는 음수 부호를 나타내는 연산자이다.- 부호 비트만을 변경하고 나머지 비트는 유지한다.