Vienna
백준2830번) 행성 X3 본문
https://www.acmicpc.net/problem/2830
2830번: 행성 X3
상근이는 초등학교 졸업 여행으로 외계 행성 X3에 방문했었다. 이 행성에 사는 사람들의 이름은 모두 자연수이다. 행성의 거주민은 모두 서로를 알고 있다. 두 X3인은 그들의 친밀도를 자신의 이
www.acmicpc.net
◇ 문제
상근이는 초등학교 졸업 여행으로 외계 행성 X3에 방문했었다. 이 행성에 사는 사람들의 이름은 모두 자연수이다. 행성의 거주민은 모두 서로를 알고 있다. 두 X3인은 그들의 친밀도를 자신의 이름을 이진수로 바꾸어서 계산한다. 두 이름을 이진수로 바꾸고, 자리수가 짧은 쪽을 기준으로 정렬한다. 이때, 두 이진수의 각 자리 아래에 두 자리가 같으면 0을, 다르면 1을 적는다. 이 결과 이진수를 다시 10진수로 바꾸면 그들의 친밀도가 된다.
예를 들어, 10과 19의 친밀도는 25이다.
1 0 0 1 1 = 19
0 1 0 1 0 = 10
--------------
1 1 0 0 1 = 25
행성의 가치는 이 섬에 있는 모든 친밀도의 합이다. 행성 거주민들의 이름이 주어졌을 때, 행성의 가치를 구하는 프로그램을 작성하시오.
◇ 입력
첫째 줄에 X3 거주민의 수 N이 주어진다. (1 ≤ N ≤ 1,000,000) 다음 N개의 줄에는 거주민의 이름이 주어진다. 이름은 1,000,000보다 작거나 같은 자연수이다.
◇ 출력
첫째 줄에 행성 X3의 가치를 출력한다.
◆ 풀이
XOR 연산을 하라는 의미다.
x ^ y 한 값을 모두 구한 뒤 더한 값을 2분의 1 하면 금방 구할 수 있을 것이다.
하지만 다른 말로 하면 먼저 계산한 i보다 j가 큰 경우에만 연산을 하면 된다는 의미이다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
int[] input = new int[n];
for(int i=0; i<n; i++){
input[i] = Integer.parseInt(br.readLine());
}
int result = 0;
for(int i = 0; i<n; i++){
for(int j = n-1; j>i; j--){
result += input[i] ^input[j];
}
}
System.out.println(result);
}
}
생각해보면 경우의 수가 N*(N-1)/2 개이기 때문에 시간초과가 나올 수 있다.
현재 나의 코드는 시간 복잡도가 O(N^2)이다.
시간 제한은 1초. 최소 O(N)으로 줄여야 가능할 것으로 보인다.
어떻게 하면 시간 복잡도를 줄일 수 있을까?
좀 오래 고민해보았지만 딱히 떠오르는 수가 없어 힌트를 얻고자 검색해보았다.
그랬더니 동일한 수의 개수를 센 뒤 해당 자리의 수를 곱한 값을 누적시키면 된다고 되어있다.
그래서 코드를 다시 작성해보았다.
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int n = Integer.parseInt(br.readLine());
// 1백만은 2의 20승보다 작기 때문
int[] input = new int[20];
final int checkBit = 0b1;
for(int i=0; i<n; i++){
int value = Integer.parseInt(br.readLine());
int index = 0;
while(value>0){
input[index++]+=value&checkBit;
value>>=1;
}
}
final long val = 1L;
long result = 0;
for(int i = 0, iMax = input.length; i<iMax; i++){
int cnt = input[i];
if(cnt==0)
continue;
result+=(val<<i)* cnt * (n-cnt);
}
System.out.println(result);
}
}
'알고리즘 문제 풀이' 카테고리의 다른 글
프로그래머스) 한 번만 등장한 문자 (0) | 2023.05.24 |
---|---|
백준10807번) 개수 세기 (1) | 2023.05.16 |
백준9012번) 괄호 (0) | 2023.05.16 |
프로그래머스) 숫자 문자열과 영단어 (0) | 2023.05.16 |
프로그래머스) 짝수는 싫어요 (0) | 2023.05.15 |