리뷰
https://www.acmicpc.net/problem/24955
문자열을 통해 숫자를 이어 붙이기를 구현했다.
전역 변수
- MOD : 모듈러 연산을 위한 상수 변수
- N : 배열의 최대 크기를 정의할 상수 변수
- n : 집의 개수를 저장할 변수
- q : 쿼리의 개수를 저장할 변수
- nodes : 대문에 쓰여있는 수를 저장할 배열
- v : 방문 여부를 체크하기 위한 배열
- edges : 인접 리스트를 저장하기 위한 벡터 배열
- P : 현재 노드 node와 이어 붙인 수 cv를 정의할 구조체
함수
1. bfs
string bfs(int sn, int en)
너비 우선 탐색을 통해 시작 지점부터 목표 지점까지 방문하며 이어 붙인 수를 구하기 위한 함수
- 매개 변수로 시작 지점의 번호 sn, 도착 지점의 번호 en을 전달 받는다.
- P타입의 큐 q를 초기화 하고, 시작 지점의 번호 sn, 해당 지점의 대문에 쓰여있는 수 nodes[sn]을 push한다.
- 시작 노드에 방문처리 후 q가 빌 때 까지 while 루프를 순회한다.
- 매 루프마다 요소를 꺼내주고, 만약 현재 노드 cn이 en에 도달했다면 현재 이어 붙인 수 cv를 리턴한다.
- 기저 조건에 해당하지 않는다면 인접 리스트를 순회하며 방문하지 않은 노드로의 이동을 진행한다.
- 이동 진행 후엔 cv에 해당 노드의 대문에 쓰여있는 수를 더해 변수 nv에 저장해 준다.
- nv를 정수형으로 변경한 값이 MOD보다 크다면 MOD로 나눈 나머지를 nv에 저장해 준다.
- q에 다음 노드 nn과 새로운 이어 붙인 수 nv를 push해준다.
문제풀이
- n, q에 값을 입력 받고, n개의 노드를 순회하며 nodes배열에 대문 앞에 쓰인 수를 저장ㅈ해 준다.
- n - 1개의 간선을 입력 받고, 양방향 간선으로 인접 리스트를 초기화 해준다.
- q개의 쿼리를 받아 변수 a, b에 노드 번호를 입력 받고, memset 메서드를 통해 v배열을 초기화 해준다.
- bfs함수에 a, b를 매개 변수로 전달하여 a에서 b로 가면서 이어 붙인 수를 리턴하고 해당 값을 출력해 준다.
트러블 슈팅
- long long타입으로는 최악의 케이스 10000000001000000000을 정수형으로 변환할 수 없었다.
- unsigned long long타입을 사용해 주면 위 최악의 케이스를 정수형으로 변환할 수 있었다.
- 따라서 long long타입을 unsigned long long으로, 정수 파싱을 stoull 메서드를 통해 진행해 AC를 받았다.
참고 사항
- long long은 약 9 * 1e18, unsigned long long은 약 18 * 1e18범위의 정수를 담을 수 있다.
정답 코드
#include<iostream>
#include<vector>
#include<queue>
#include<string>
#include<cstring>
#define ull unsigned long long
using namespace std;
const ull MOD = 1000000007;
const int N = 1001;
int n, q;
string nodes[N];
bool v[N];
vector<int> edges[N];
struct P {
int cn;
string cv;
};
string bfs(int sn, int en) {
queue<P> q;
q.push({ sn, nodes[sn] });
v[sn] = true;
while (!q.empty()) {
P p = q.front(); q.pop();
int cn = p.cn;
string cv = p.cv;
if (cn == en) return cv;
for (int nn : edges[cn]) {
if (v[nn]) continue;
v[nn] = true;
string nv = cv + nodes[nn];
ull nvi = stoull(nv);
if (nvi > MOD) nv = to_string(nvi % MOD);
//cout << nv << "\n";
q.push({ nn, nv });
}
}
return "-1";
}
int main() {
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> q;
for (int i = 1; i <= n; ++i) cin >> nodes[i];
for (int i = 1; i <= n - 1; ++i) {
int a, b; cin >> a >> b;
edges[a].push_back(b);
edges[b].push_back(a);
}
while (q--) {
int a, b; cin >> a >> b;
memset(v, 0, sizeof(v));
cout << bfs(a, b) << "\n";
}
}
728x90
'알고리즘 공부 > C++' 카테고리의 다른 글
[G4] 백준 29811번 지각하기 싫어 C++ 멀티셋 (0) | 2025.03.08 |
---|---|
[G2] 백준 1445번 일요일 아침의 데이트 C++ 다익스트라 (0) | 2025.03.07 |
[G4] 백준 12886번 돌 그룹 C++ 너비 우선 탐색 (0) | 2025.03.05 |
[G4] 백준 31792한빛미디어 (Hard) C++ 트리 셋, 이분 탐색 (0) | 2025.03.04 |
[G5] 백준 1374번 강의실 C++ 그리디 알고리즘, 정렬, 우선순위 큐 (0) | 2025.03.03 |