티스토리 뷰
728x90
문제
풀이
고려해야할 점
더보기
- 순서 관계 변경:
- 주어진 순서에 대해 여러 쌍의 순서 관계를 변경해야 하므로, 현재 상태의 순서와 이후에 주어지는 관계 변경이 어떻게 영향을 미치는지 추적해야 한다.
- currentPosition 배열에서 순서를 변경할 때, 중복된 위치나 범위 밖의 위치가 발생하지 않도록 해야 한다.
- 유효성 검사:
- 변경된 순서가 유효한지 검증하는 과정에서 resultMap에 중복된 위치가 없도록 해야 한다.
- 위치가 배열 범위를 벗어나는지, 중복된 노드가 있는지 체크하여 잘못된 순서인 경우 “IMPOSSIBLE”을 출력한다.
- "?"인 경우는 존재하지 않는다. 올바른 순위를 결정할 수 없으면 모두 "IMPOSSIBLE"이다.
- 최적화 고려:
- 많은 쌍의 관계 변경이 있을 수 있으므로 효율적으로 현재 순서를 업데이트하는 방법이 필요하다.
- O(n)의 시간 복잡도로 문제를 해결해야 한다.
알고리즘 분류(백준 기준)
더보기
- 그래프 이론
- 위상 정렬
- 방향 비순환 그래프
풀이 아이디어
더보기
- 초기화:
- 각 테스트 케이스에 대해 주어진 초기 순서를 arr 배열에 저장한다. 각 인덱스는 순위를 의미한다.
- originalPosition 배열을 통해 각 노드의 초기 위치를 저장하여, 초기 상태를 기록합니다. 각 인덱스는 팀 번호를 의미하며 값은 팀의 순위를 의미한다.
- currentPosition 배열을 사용해 관계 변경에 따라 위치를 갱신할 수 있도록 초기 위치를 복사한다.
- 순위를 두 개의 배열에 저장하는 이유는 순위 비교와 순위 변경을 따로 진행하기 위해서이다. 순위 변경은 초기 순위를 기준으로 진행한다.
- 관계 업데이트:
- 각 쌍 (a, b)의 관계를 읽어와 originalPosition 배열에서 a와 b의 초기 위치를 비교합니다.
- a의 위치가 b보다 뒤에 있으면, a를 한 칸 앞으로, b를 한 칸 뒤로 이동시킵니다. 반대의 경우 a를 뒤로, b를 앞으로 이동시킵니다. 이렇게 하는 이유는 두 관계쌍이 존재할 경우, 한 쪽은 순위가 하나 올라가고 다른 한 쪽은 순위가 내려갈 수 밖에 없다. 모든 관계 쌍에 대하여 순위 증감을 실시한 후 올바른 순위가 나오면 정보가 맞는 것이다.
- 이 과정을 통해 모든 관계를 반영하여 currentPosition 배열을 업데이트한다.
- 유효성 검사 및 출력:
- currentPosition 배열을 resultMap에 매핑하여 각 노드의 위치가 범위를 벗어나거나 중복되지 않는지 검증한다.
- 만약 잘못된 순서가 발생한다면, "IMPOSSIBLE"을 결과에 추가하고, 그렇지 않으면 최종 순서를 출력한다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
StringBuilder sb = new StringBuilder();
// 테스트 케이스의 개수 입력
int T = Integer.parseInt(br.readLine());
// 테스트 케이스별 처리
for (int t = 1; t <= T; t++) {
// 노드 개수 입력
int n = Integer.parseInt(br.readLine());
int[] arr = new int[n]; // 입력 순서 저장
int[] originalPosition = new int[n + 1]; // 입력 순서에 따른 위치 저장
int[] currentPosition = new int[n + 1]; // 현재 위치 저장
// 노드의 초기 상태 입력
st = new StringTokenizer(br.readLine());
for (int i = 0; i < n; i++) {
arr[i] = Integer.parseInt(st.nextToken());
originalPosition[arr[i]] = i; // 노드의 초기 위치 설정
}
// 초기 위치를 현재 위치 배열로 복사
for (int i = 1; i <= n; i++) {
currentPosition[i] = originalPosition[i];
}
// 관계 변경 횟수 입력
int m = Integer.parseInt(br.readLine());
// 각 관계 변경에 따른 위치 조정
for (int i = 0; i < m; i++) {
st = new StringTokenizer(br.readLine());
int a = Integer.parseInt(st.nextToken());
int b = Integer.parseInt(st.nextToken());
// 두 노드의 위치 비교하여 조건에 따라 위치 조정
if (originalPosition[a] > originalPosition[b]) {
currentPosition[a]--;
currentPosition[b]++;
} else {
currentPosition[a]++;
currentPosition[b]--;
}
}
// 결과 검증 및 출력
boolean isImpossible = false;
int[] resultMap = new int[n];
for (int i = 1; i <= n; i++) {
int pos = currentPosition[i];
// 위치가 범위를 벗어나거나 중복된 경우
if (pos < 0 || pos >= n || resultMap[pos] != 0) {
isImpossible = true;
break;
} else {
resultMap[pos] = i; // 결과 배열에 노드 위치 저장
}
}
// 결과 출력
if (isImpossible) {
sb.append("IMPOSSIBLE\n");
} else {
for (int i = 0; i < n; i++) {
sb.append(resultMap[i]).append(" ");
}
sb.append("\n");
}
}
System.out.print(sb);
}
}
728x90
'알고리즘 > 코딩테스트' 카테고리의 다른 글
[프로그래머스] LV3. 산 모양 타일링 문제 풀이 (0) | 2024.12.09 |
---|---|
[백준]15922번 아우으 우아으이야!! 문제 풀이 (0) | 2024.11.08 |
[백준] 16562번 친구비 문제 풀이 (2) | 2024.11.05 |
[백준]4196번 도미노 문제풀이 (1) | 2024.10.30 |
[백준]2568번 전깃줄-2 문제 풀이 (0) | 2024.10.29 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
TAG
- 전자회로
- 인프런강의후기
- 생성형 AI
- SSAFY
- 위니브엠베서더
- 파이썬
- django
- 위니브
- Python
- 코딩테스트
- 인프런강의
- 알고리즘
- 알고리즘이론
- 웹개발
- 오블완
- 티스토리챌린지
- 웹
- 웹프로그래밍
- 프로그래머스
- SSAFYcial
- 인프런
- 제주코딩베이스캠프
- PANDAS
- 더오름
- 백준알고리즘
- ssafy기자단
- 백준
- numpy
- it도서큐레이션
- dataframe
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
글 보관함
250x250