
Codeforces Round #742 (Div. 2)-B. MEXor Mixup
falconlee236
·2021. 11. 16. 20:26
문제 설명
엘리스는 밥에게 두 정수
밥이 적은 가능한 최소길이를 가진 배열은 무엇일까?
배열의
Input
첫번째 줄에는 테스트 케이스의 개수
각 테스트케이스는 각각 배열의
Output
각 테스트 케이스마다 배열의
Example
input
5
1 1
2 1
2 0
1 10000
2 10000
output
3
2
3
2
3
문제 접근
사용한 알고리즘: 비트마스킹, 구현
걸린 시간 : 00:20
이 문제는 구현이 어려운게 아니라 이 MEX라는 값의 개념을 모르면 그냥 풀수가 없다. 나도 이 문제를 풀면서 MEX라는 개념을 처음 알았는데, 다음과 같다. 배열에 들어있는 원소가 음이 아닌 정수를 만족한다고 가정할 때, 배열에 있는 원소가 아닌 정수 중에서 가장 작은 값을 말한다.
이렇게만 적으면 당최 뭔 소린지 전혀 이해할 수 없다. 그렇기 때문에 예시를 들어서 설명을 하자.
배열
첫번째 예시에서는 배열
두번째 예시에서는 배열
이정도면 MEX값은 완벽히 이해했을 것이라고 믿는다. 그러면 MEX값이
XOR값은 그냥 모든 배열의 XOR값을 계산하면 되는데, 계산의 편의를 위해서
그렇다면 이 값을 왜 계산해 뒀을까? 문제 풀이에 반드시 필요한 값이기 때문이다. 출력값이 a, b이고
모든 경우를 그냥 만족하기 때문에 배열에 추가로 원소를 삽입할 필요가 없다. 이 때 배열의 길이는 인 경우, 두가지 경우가 추가로 존재한다. 인 경우 값이 가 아니므로 배열에 를 추가하면 된다. 그러면 이므로 문제 조건을 만족한다. 이때 배열의 길이는 이다. 인 경우 값이 이므로 배열에 를 추가 할 수 없다. 추가하면 MEX값이 가 아니게 되기 때문이다. 그래서 우회하는 방법을 써야하는데, 이것 또한 bitwise XOR연산의 성질을 사용한다. 임의의 매우 큰 수를 라고 하자. 이므로 배열에 와 을 추가하면 되므로 이때 배열의 길이는 이다.
정답 코드
#include <cstdio>
int dp[300001];
int main(){
for(int i = 1; i <= 300000; i++) dp[i] = (dp[i - 1] ^ i);
int t; scanf("%d", &t);
while(t--){
int a, b; scanf("%d %d", &a, &b);
int k = dp[a - 1];
if(k == b) printf("%d\n", a);
else{
if((k ^ b) != a) printf("%d\n", a + 1);
else printf("%d\n", a + 2);
}
}
}
'알고리즘 > codeforces' 카테고리의 다른 글
Codeforces Round #745 (Div. 2)-A. CQXYM Count Permutations (0) | 2021.11.16 |
---|---|
Codeforces Round #742 (Div. 2)-C. Carrying Conundrum (0) | 2021.11.16 |
Codeforces Round #742 (Div. 2)-A. Domino Disaster (0) | 2021.11.16 |
Educational Codeforces Round 113 (Rated for Div. 2)-C. Jury Meeting (0) | 2021.11.16 |
Educational Codeforces Round 113 (Rated for Div. 2)-B. Chess Tournament (0) | 2021.11.16 |