카테고리 없음
백준 13144번 <List of Unique Numbers>
seungh2
2023. 10. 6. 15:49
백준 알고리즘 13144번
https://www.acmicpc.net/problem/13144
13144번: List of Unique Numbers
길이가 N인 수열이 주어질 때, 수열에서 연속한 1개 이상의 수를 뽑았을 때 같은 수가 여러 번 등장하지 않는 경우의 수를 구하는 프로그램을 작성하여라.
www.acmicpc.net
13144번
문제 해결
two pointer를 사용하여 문제를 풀이했다.
작은 테스트케이스를 손으로 확인하며 찾은 규칙을 보니 two pointer를 사용하면 될 것 같았다.
하나씩 모두 구해보니 end를 기준으로 end-1까지의 숫자로 만든 수열에 end를 추가하면 된다는 것을 알 수 있었다.
이때, 중간에 같은 숫자가 있는 경우에는 start를 update 시켜주어야 하는데 다음 그림을 보면 쉽게 이해할 수 있다.
2가 중복으로 나오기 때문에 중간에 start를 2로 update 한 것을 확인할 수 있다. 이렇게 하면 [3, 2, 1] 을 수열로 생각할 수 있게 된다.
사용하는 변수는 다음과 같다.
- use[i] : 숫자 i를 사용했으면 true 사용하지 않았으면 false
- start : 고려하는 수열의 시작 인덱스
- end : 고려하는 수열의 끝 인덱스
- acc : 같은 수가 등장하지 않는 경우의 수
N이 100,000개이고, 수열의 숫자가 모두 다르다면 ( 100,000 * (100,000 + 1) ) / 2 = 5,000,050,000 로 최대 50억이 될 수 있기 때문에 long 타입을 사용하였다.
프로세스는 다음과 같다.
- 방금 추가한 숫자 (수열의 end 인덱스 숫자)를 사용했다면 사용하지 않게 만든다.
- 방금 추가한 숫자를 사용하지 않을 때까지 start를 증가시켜가며 숫자를 사용하지 않는다.
- 방금 추가한 숫자를 사용한다. end - start + 1 개의 경우의 수를 구할 수 있다.
- 이전에 구성된 경우들에 방금 추가한 숫자를 이어붙이는 경우와 방금 추가한 숫자 혼자 있는 경우
- end를 1 증가시킨다.
코드
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class BOJ_13144 {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int N = Integer.parseInt(br.readLine());
int[] number = new int[N];
String[] inArr = br.readLine().split(" ");
int max = 0;
for (int i = 0; i < N; i++) {
number[i] = Integer.parseInt(inArr[i]);
max = Integer.max(max, number[i]);
}
boolean[] use = new boolean[max + 1];
int start = 0;
int end = 0;
long acc = 0;
while (end < N) {
// 방금 추가한 숫자가 이미 사용 중이라면
if (use[number[end]]) {
// 해당 숫자 사용 안하기
while (start <= end) {
if (number[end] == number[start]) {
start++;
break;
}
use[number[start]] = false;
start++;
}
}
// 방금 추가한 숫자 사용
use[number[end]] = true;
acc += (end - start) + 1;
end++;
}
System.out.println(acc);
}
}
결과
728x90