[BOJ][Math][실1][20153] 영웅이는 2의 거듭 제곱을 좋아해! 영웅이는 2의 거듭 제곱을 좋아해!
문제 링크
첫 번째 풀이
알고리즘
쉽게 정리한 XOR에서 xor의 특징을 정리해두었습니다.
우선 아래 문장 의미를 제대로 이해해야합니다.
1
그 후 각 정수 x에 대해 2x가 홀수 개 존재하면 2x를 더하고, 짝수 개 존재하면 더하지 않는다. 이렇게 했을 때 얻을 수 있는 최대 합을 2번 출력하라.
모든 N개의 자연수를 영웅이의 표현법으로 바꾼 뒤, 전체에 대해서 항의 갯수가 홀수개인 2^x만 더해서 출력하라는 말입니다.
그런데 짝수 개면 더하지 않는다는 부분에서, XOR의 특징이 사용됩니다. a^a^b처럼 같은 값을 짝수번 XOR하게 되면 0이 됩니다. 그리고 0이랑 XOR을 하면 값이 변하지 않습니다.
예제 입력 1에 대해서 자연수 전체를 xor해둔 x를 저장합니다.
x = 5 ^ 7 ^ 11
그리고 최대 한 개의 자연수를 제거해야하니 아래의 경우 중 최대값을 찾습니다.
1
2
3
4
x // 0개의 자연수를 제거한 경우
x ^ 5 // 1개의 자연수를 제거한 경우
x ^ 7 // 1개의 자연수를 제거한 경우
x ^ 11 // 1개의 자연수를 제거한 경우
XOR을 사용한 결과의 최대값을 찾았기 때문에 위 4개의 XOR 결과들은 모두 2^x 항을 1개씩만 가지고 있습니다. 만약 짝수개였다면 XOR의 특징에 의해서 사라질테니까요
1
2
3
4
x // 5 ^ 7 ^ 11
x ^ 5 // 7 ^ 11
x ^ 7 // 5 ^ 11
x ^ 11 // 5 ^ 7
정답 코드
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
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MAX = 2'222'225;
int v[MAX];
int main()
{
//freopen("input.txt", "r", stdin);
ios_base::sync_with_stdio(0); cin.tie(0);
int n; cin >> n;
int x = 0;
for (int i = 0; i < n; i++) {
cin >> v[i];
x ^= v[i];
}
int ans = x;
//cout << bitset<8>(ans) << "\n";
for (int i = 0; i < n; i++) {
ans = max(ans, x ^ v[i]);
//cout << bitset<8>(ans) << "\n";
}
cout << ans << ans << "\n";
return 0;
}
Success Notice: XOR 개념을 사용한 문제를 풀어봤습니다. 수고하셨습니다.
Leave a comment