[백준 BOJ] 4358번 생태학 (C++/cpp)

2025. 3. 5. 16:00PS (Program Solving)/BOJ (백준)

문제 설명

https://www.acmicpc.net/problem/4358

 

백준 BOJ 4358번 생태학 문제 사진

 

접근 방법 - 벡터와 맵을 활용한 연산 문제

백준의 4358번 문제는 벡터와 맵 자료구조를 함께 사용하여 해결할 수 있는 문제이다.

해당 문제는, 나무들의 종이 모두 입력으로 주어질 때 각 종의 분포 비율을 각각 구하여 사전 순으로 정답을 출력해야 하는 문제이다.

이때 각 종의 분포 비율을 출력할 때 소수점 넷째 자리까지 출력하라고 명시되어 있기 때문에 이 점까지 함께 참고하길 바란다.

 

벡터와 맵 자료구조를 활용하는 데에 익숙하다면, 생각보다 어렵지 않게 풀 수 있을 것으로 예상된다.

필자의 경우에는 2개의 자료구조를 아래의 용도대로 활용하였다.

  • vector<string> 각 나무 종의 이름을 저장하는 데에 활용 (나무 종의 사전 순 정렬에 필요)
  • map<string, double> :: 각 나무 종의 분포 수를 저장하는 데에 활용 (비율 연산에 필요)

그리고 필자는 해당 문제를 C++로 해결하였는데, 소수점 넷째 자리까지 출력하기 위하여 아래 구문을 사용하였다.

cout << fixed;
cout.precision(4);

 

연산에 대한 상세한 설명은 아래에 기재해 놓으니, 혹여나 해당 문제를 해결하는 데에 어려움을 겪고 있다면 아래의 설명과 코드를 참고해 보길 바란다.

필자는 아래의 순서대로 코드를 작성하여 문제를 해결하였다.

 

코드의 실행 순서

1) 벡터(n) 구조와 맵(tree) 구조를 전역 변수로 미리 선언해 둔다.

각각의 사용처는 위에서 언급한 대로, 각 나무 종의 이름과 총 분포 수를 저장하는 데에 활용할 예정이다.

 

2) 전체 나무 수를 저장할 변수(whole)를 0으로 초기화하여 선언해 둔다.

 

3) 무한 반복문을 활용하여, 아래의 연산을 수행한다.

- 나무 종의 이름(name)을 입력받는다.

이때 공백을 포함한 값도 입력으로 주어지기 때문에, C++로 문제를 해결할 경우엔 아래의 구문을 통하여 입력받도록 한다.

getline(cin, name);

- 하나의 나무에 대해 입력을 받았기 때문에, 전체 나무 수를 저장하는 whole에 1을 더한다.

- tree의 key값들 중 name값이 존재하지 않는다면, 이는 처음 발견된 나무임을 뜻하기 때문에, 이 경우엔 n에 name의 값을 추가한 뒤 tree[name]의 value값을 1로 설정하여 tree에 값을 추가하도록 한다.

tree의 key값으로 존재한다면, 앞에서 이미 동일한 종의 나무가 발견되었음을 뜻하기 때문에, 이 경우엔 tree[name]의 value값에 1을 더하도록 한다.

- cin.eof()를 통하여, 입력의 끝에 다다랐다면 해당 반복문을 종료하도록 한다.

(몇 그루의 나무가 있는지에 대해서는 입력값으로 주어지지 않기 때문에, 아래 구문을 통하여 반복문을 종료하게끔 해야 한다.)

if (cin.eof() == true) { break; }

 

4) 나무 종의 이름이 저장된 n에 대하여, sort()를 통하여 값들을 사전 순으로 정렬한다.

 

5) n의 크기만큼 반복문을 실행하여, 사전 순으로 정렬된 나무 이름들에 대한 각 정답을 출력한다.

(각 나무 종의 분포수를 의미하는 tree의 각 value값에 대하여, 전체 나무 수인 whole로 나눈 뒤 100을 곱하면, 해당되는 나무의 분포 비율을 구할 수 있다.)

 

6) 순차적으로 정답을 출력하였다면, 프로그램 실행을 종료한다.

반응형

 

성공한 코드

#define _CRT_SECURE_NO_WARNINGS
#pragma warning(disable: 4996)
#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <map>
#define endl '\n'
using namespace std;

//백준 4358번 코드
vector<string> n;
map<string, double> tree;
int main() {
	ios::sync_with_stdio(false);
	cin.tie(NULL);	cout.tie(NULL);
	cout << fixed;
	cout.precision(4);
	
	double whole = 0;
	while (1) {
		string name;
		getline(cin, name);
		if (cin.eof() == true) { break; }

		whole++;
		if (tree.find(name) == tree.end()) {
			n.push_back(name);
			tree.insert({ name, 1 });
		}
		else {
			tree[name]++;
		}
	}
	sort(n.begin(), n.end());

	for (int i = 0; i < n.size(); i++) {
		cout << n[i] << " " << tree[n[i]]*100 / whole << endl;
	}
}

 

제출 결과

백준 BOJ 4358번 생태학 문제 C++ 제출 결과

(2023.01.17 백준 4358번 문제 제출 결과)

로직 때문에 헤맨 줄 알았으나 자잘한 것들로 삐걱거렸다 카더라;;

반응형