문제 링크
문제
N개의 수가 주어졌을 때, XOR한 값이 가장 큰 두 수를 찾는 프로그램을 작성하시오.
즉, A1, A2, ..., AN 중에서 i ≠ j이면서 Ai XOR Aj 가 가장 큰 것을 찾아야 한다.
입력
첫째 줄에 N (2 ≤ N ≤ 100,000)이 주어진다.
둘째 줄에는 N개의 수가 주어진다. 입력으로 주어지는 수는 1,000,000,000보다 작거나 같은 음이 아닌 정수이다.
출력
첫째 줄에 XOR한 값이 가장 큰 두 수의 XOR한 결과를 출력한다.
예제 입력 1
5
1 2 3 4 5
예제 출력 1
7
예제 입력 2
5
0 1 0 1 0
예제 출력 2
1
예제 입력 3
6
1 2 4 8 16 32
예제 출력 3
48
알고리즘 분류
- 트라이
풀이
정수들을 이진수로 변환하고 트라이에 insert한다.
그리고 각 이진수를 통해 트라이를 탐색하면서 최댓값을 구한다.
최댓값을 구하기 위해서는 높은 자리수부터 순차적으로 비트를 비교해서 최대한 1을 많이 갖도록 해야 한다.
코드
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#define MAX 100001
#define LL long long
#define FASTIO cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);
using namespace std;
struct TRIE {
bool isEnd;
LL finish_Number;
TRIE* Child[2];
TRIE() {
isEnd = false;
for (int i = 0; i < 2; i++) {
Child[i] = nullptr;
}
}
void insert_Pattern(string Pattern, LL Number) {
TRIE* NowTrie = this;
for (int i = 0; i < Pattern.size(); i++) {
int Now = Pattern[i] - '0';
if (NowTrie->Child[Now] == nullptr) {
NowTrie->Child[Now] = new TRIE;
}
NowTrie = NowTrie->Child[Now];
}
NowTrie->isEnd = true;
NowTrie->finish_Number = Number;
}
LL query(string NowS, LL NowN) {
LL Result = NowN;
TRIE* NowTrie = this;
for (int i = 0; i < NowS.size(); i++) {
int Now = NowS[i] - '0';
if (NowTrie->Child[Now ^ 1] != nullptr) {
NowTrie = NowTrie->Child[Now ^ 1];
}
else {
NowTrie = NowTrie->Child[Now];
}
}
Result ^= NowTrie->finish_Number;
return Result;
}
};
int N;
LL A, Max_Length;
vector<LL> Numbers;
vector<string> Strings;
LL Answer;
string make_String(int Number) {
string Result = "";
while (1) {
if (Number == 0) {
break;
}
Result = to_string(Number % 2) + Result;
Number /= 2;
};
return Result;
}
void settings(TRIE* Root) {
for (int i = 0; i < N; i++) {
string Now = Strings[i];
int NowL = (int)Now.length();
int Sub = Max_Length - NowL;
string tmp = "";
while (Sub--) {
tmp += '0';
};
Strings[i] = tmp + Now;
Root->insert_Pattern(Strings[i], Numbers[i]);
}
for (int i = 0; i < N; i++) {
TRIE* NowTrie = Root;
string NowS = Strings[i];
int NowN = Numbers[i];
Answer = max(Answer, NowTrie->query(NowS, NowN));
}
}
void find_Answer() {
cout << Answer << "\n";
}
void input() {
TRIE* Root = new TRIE();
cin >> N;
for (int i = 0; i < N; i++) {
cin >> A;
Numbers.push_back(A);
string NewA = make_String(A);
Strings.push_back(NewA);
Max_Length = max(Max_Length, (LL)NewA.length());
}
settings(Root);
find_Answer();
delete Root;
}
int main() {
FASTIO
input();
return 0;
}
'BOJ > Platinum ~ Diamond' 카테고리의 다른 글
[BOJ/Platinum 2] 백준 13547 수열과 쿼리 5(C++) (5) | 2023.05.04 |
---|---|
[BOJ/Platinum 3] 백준 16903 수열과 쿼리 20(C++) (0) | 2023.05.03 |
[BOJ/Platinum 3] 백준 13504 XOR 합(C++) (1) | 2023.05.03 |
[BOJ/Platinum 3] 백준 19585 전설(C++) (0) | 2023.05.03 |
[BOJ/Diamond 5] 백준 6300 단어 퍼즐(C++) (0) | 2023.05.02 |