algorithm/Baekjoon Online Judge
[BOJ] 10157 자리배정(Java)
eo_neunal
2022. 2. 27. 00:25
문제
https://www.acmicpc.net/problem/10157
10157번: 자리배정
첫 줄에는 공연장의 격자 크기를 나타내는 정수 C와 R이 하나의 공백을 사이에 두고 차례대로 주어진다. 두 값의 범위는 5 ≤ C, R ≤ 1,000이다. 그 다음 줄에는 어떤 관객의 대기번호 K가 주어진다.
www.acmicpc.net
풀이
- 사각형의 가장 바깥 쪽 테두리부터 가장 안쪽 테두리까지 탐색하며 k가 속한 테두리를 찾는다.
- r X c 사각형일 때 시작 위치 (x,y)에서의 대기번호가 1이라면 같은 테두리의 마지막 대기번호는 r*2 + c*2 - 4가 된다.
- 마지막 대기번호보다 k가 크면 x,y는 1씩 증가, r, c는 2씩 감소, 다음 대기번호는 마지막 대기번호+1이 된다.
- k가 속한 테두리를 찾으면 x,y부터 시계방향으로 탐색하며 k를 찾는다.
소스 코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
private static final int[][] DELTAS = {{0, 1}, {1, 0}, {0, -1}, {-1, 0}};
private static int r;
private static int c;
private static int k;
private static int waitingNumber;
public static void main(String[] args) throws IOException {
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer stringTokenizer = new StringTokenizer(bufferedReader.readLine());
c = Integer.parseInt(stringTokenizer.nextToken());
r = Integer.parseInt(stringTokenizer.nextToken());
k = Integer.parseInt(bufferedReader.readLine());
if (k > r * c) {
System.out.println(0);
return;
}
waitingNumber = 1;
int x = 1;
int y = 1;
int edge = r * 2 + c * 2 - 4;
while (edge < k) {
r -= 2;
c -= 2;
x++;
y++;
waitingNumber = edge+1;
edge += r * 2 + c * 2 - 4;
}
for (int i = 0, deltasLength = DELTAS.length; i < deltasLength; i++) {
int[] delta = DELTAS[i];
int dx = x + delta[0];
int dy = y + delta[1];
while (canGo(i, dx, x, dy, y)) {
dx += delta[0];
dy += delta[1];
}
x = dx - delta[0];
y = dy - delta[1];
if (waitingNumber - 1 == k) {
break;
}
}
System.out.println(x + " " + y);
}
private static boolean canGo(int direction, int dx, int x, int dy, int y) {
if (direction < 2) {
return dx >= x && dx < x + c && dy >= y && dy < y + r && waitingNumber++ != k;
} else {
return dx <= x && dx > x - c && dy <= y && dy > y - r && waitingNumber++ != k;
}
}
}