-
[C++] 백준-1620 (나는야 포켓몬 마스터 이다솜)CS & Algorithm & Data Structure & C/C++ 2023. 8. 15. 13:30반응형
문제는 쉽게 말해서, 문자열의 경우에는 번호를 말해야하고, 숫자의 경우에는 번호에 해당하는 문자를 출력하는 것이다.
해결 방법은 아래와 같다.
#include <bits/stdc++.h> using namespace std; int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); int N, M; cin >> N >> M; unordered_map<string, int> nameToNumber; vector<string> numberToName(N + 1); for (int i = 1; i <= N; ++i) { string name; cin >> name; nameToNumber[name] = i; numberToName[i] = name; } for (int i = 0; i < M; ++i) { string query; cin >> query; if (isdigit(query[0])) { int number = atoi(query.c_str()); cout << numberToName[number] << '\n'; } else { cout << nameToNumber[query] << '\n'; } } return 0; }
한 줄 한 줄 설명해보겠다.
(단, 사용 방법은 C++을 잘 사용하는 것이 아니라, 코딩테스트를 위한 기준으로 사용된다)
#include <bits/stdc++.h>
우선 C++ 표준 라이브러리의 모든 헤더 파일을 포함하는 방법 중 하나로 위와 같은 방식을 사용한다.
이렇게 사용하면 필요한 라이브러리를 모두 포함시켜 편리하게 사용할 수 있다.
using namespace std;
그리고 std를 계속 사용하면 귀찮으니 namespace 없이 사용할 수 있도록 지정해둔다.
int main() { ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL);
여기서부터 main 함수의 시작인데, ios_base::syc_with_stdio(false)는 C++의 cin, cout을 C 표준 입출력과 동기화 하지 않도록 설정하는 것이다.
여기서 "C 표준 입출력과 동기화 하지 않도록 설정" 한다는 것의 의미는 무엇일까?
기본적으로 사용자로부터 입력을 받거나 결과를 출력할 때, C++의 cin과 cout을 은 scanf와 printf와 동기화 되어있다.
즉, 함께 사용될 때 문제가 없도록 설계가 되어있다.
하지만 이런 동기화는 프로그램의 입출력 속도를 느리게 만들 수 있기 때문에 동기화하지 않도록 설정하는 것이다.
동기화 되지 않도록 설정한 만큼 ios_base::syc_with_stdio(false)을 사용했다면 cin, cout만 사용하거나, scanf, printf만 사용하는 것이 좋다.
이어서 cin.tie(NULL)을 통해서 입력과 출력을 동기화하지 않도록 해주고, cout.tie(NULL)을 통해서 출력 버퍼를 비우지 않도록 설정한다.
그런데 위에서 ios_base::syc_with_stdio(false)는 입출력 동기화를 막는다고 했는데, 왜 cin.tie(NULL)을 하는걸까?
엄밀하게 말하자면 ios_base::syc_with_stdio(false)의 경우에는 C++의 입출력 버퍼와 C 표준 입출력 버퍼를 동기화하지 않도록 설정하는 것이고, cin.tie(NULL)은 cin과 cout 사이의 동기화를 끊어 입출력 속도를 향상 시키며, cin과 cout을 함께 사용할 때만 적용된다.그리고 cout.tie(NULL)을 통해서 출력 버퍼를 비우지 않도록 설정하면서 입출력 속도를 향상 시킬 수 있는 것이다
int N, M; cin >> N >> M;
그리고 N과 M을 입력받는다.
N은 포켓몬의 개수, M은 쿼리의 개수이다.
unordered_map<string, int> nameToNumber; vector<string> numberToName(N + 1);
nameToNumber는 포켓몬 이름과 번호를 매핑하는 해시 맵이고, numberToName은 번호와 포켓몬 이름을 매핑하는 백터이다.
for (int i = 1; i <= N; ++i) { string name; cin >> name; nameToNumber[name] = i; numberToName[i] = name; }
그리고 첫 번째 for문을 돌게 된다.
첫 번째 for문에서는 N개의 포켓몬 이름을 입력 받아서 해시 맵과 벡터에 이름과 번호를 매핑하여 저장한다.
for (int i = 0; i < M; ++i) { string query; cin >> query; if (isdigit(query[0])) { int number = atoi(query.c_str()); cout << numberToName[number] << '\n'; } else { cout << nameToNumber[query] << '\n'; } }
두 번째 M개의 쿼리를 입력받아서 for문을 돈다.
참고로 여기서 isdigit은 쉽게 말해서 숫자인지 판단하기 위한 함수이다.
매개변수로 들어온 char 타입이 10진수 숫자로 변경이 가능하다면 0이 아닌 숫자(true)를 리턴하고, 10진수 숫자로 변경이 불가하다면 0을 반환(false)한다.
atoi는 ASCII To Integer의 줄임말로 문자열을 정수 타입으로 바꾸는 함수이다.
이 외에도 atof, atol 등이 있다.
atoi = ASCII To Integer = 문자열을 정수 타입으로 변경
atof = ASCII To Double = 문자열을 실수 타입으로 변경
atol = ASCII To long int = 문자열을 long 정수 타입으로 변경
그리고 마지막으로 return 0을 하면 프로그램이 정상적으로 종료된다.
반응형'CS & Algorithm & Data Structure & C > C++' 카테고리의 다른 글
[C++] 백준-2309 일곱 난쟁이 (0) 2023.08.29 [C++] 백준-1037 약수 (0) 2023.08.16 [C++] 백준-4375 (0) 2023.08.15 백준 10430번 : 나머지 (모듈러 연산) (0) 2023.08.15 C++ 중복 없애기 (unique, erase) (0) 2023.07.01