[백준] 2892 심심한 준규 (C++)

원문 링크 : https://www.acmicpc.net/problem/2892

풀이 및 구현

문제를 정리하면 영소문자, 온점, 공백 세 종류의 문자와 0-9를 아스키 코드 값으로 xor한 결과가 16진수로 주어지면 원래 글자가 문자인지 아닌지 판별하는 문제이다.

xor하는 경우의 수가 많지 않으니 직접 시뮬레이션을 해서 값의 규칙을 파악해 보았다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// 영소문자와 xor
for (int i = 0; i < 26; i++) {
for (int j = 0; j < 10; j++) {
cout << dec << (char)(i + 'a') << ' '<< j << ": " << hex << ((i + 'a') ^ (j + '0')) << '\n';
}
}

// 공백과 xor
for (int i = 0; i < 10; i++)
cout << dec << " " << i << ": " << hex << (' ' ^ (i + '0')) << '\n';

// 온점과 xor
for (int i = 0; i < 10; i++)
cout << dec << ". "<< i << ": " << hex << ('.' ^ (i + '0')) << '\n';

위 코드를 통해 값을 확인해보면 영소문자와 xor한 결과는 모두 0x40 이상이고 온점과 공백과 xor한 결과는 모두 0x20미만이다.

따라서 16진수가 들어오면 0x40을 기준으로 이상이면 ‘.’을 출력하고 아니면 ‘-‘을 출력하면 된다.

이때 16진수 형태로 입력되므로 string으로 입력받고 앞자리로 비교했다.

1
2
3
string s; cin >> s;
if (s.front() < '4') cout << '.';
else cout << '-';

코드

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <bits/stdc++.h>
using namespace std;

int main() {
cin.tie(nullptr)->sync_with_stdio(false);

int N; cin >> N;
for (int i = 0; i < N; i++) {
string s; cin >> s;
if (s.front() < '4') cout << '.';
else cout << '-';
}
}

후기

img.png
내 예상보다 티어가 매우 높았다.

문제 예제만 보고 규칙을 예상했고, 모든 경우의 수 시뮬레이션을 했을 때 규칙을 한눈에 찾을 수 있어서 실버 3으로 예상했었는데 실버 1일 것이라고는 상상도 못했다.

https://en.cppreference.com/w/cpp/io/manip/hex

또한 위 레퍼런스를 확인해 보니 시뮬레이션에 사용했던 std::hexcin에서 사용해서 그냥 int로 받아 비교할 수도 있었다.

아래는 int로 처리한 코드이다.

1
2
3
4
5
6
7
8
9
10
11
12
13
#include <bits/stdc++.h>
using namespace std;

int main() {
cin.tie(nullptr)->sync_with_stdio(false);

int N; cin >> N;
for (int i = 0; i < N; i++) {
int n; cin >> hex >> n;
if (n < 0x40) cout << '.';
else cout << '-';
}
}