Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[그리디] 4월 12일 #9

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions [그리디] 4월 12일/11000_sample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>

using namespace std;
typedef pair<int, int> ci; // pair<int, int> -> ci

// 필요 강의실 수를 구하는 함수
int arrayRoom(int n, vector<ci> lec) { // 리턴 값: 필요한 강의실 수, 입력 값: 강의 수, 강의에 대한 정보
priority_queue<int, vector<int>, greater<>> pq; // 종료 시간을 저장하는 우선순위 큐

pq.push(-1); // 처음 인덱스 에러를 피하기 위해 음수 값 삽입. (첫번째 강의 때 갱신될 값)

for (int i = 0; i < n; i++) { // n개의 수업, 필요한 강의 수를 구하기 위한 연산
if (lec[i].first >= pq.top()) { // 종료시간이 가장 빠른 수업보다 시작시간이 같거나 느리다면 -> 같은 강의실
pq.pop(); // 같은 강의실이 가능한 강의는 삭제
}
pq.push(lec[i].second); // 기존 강의실 정보 갱신 or 새로운 강의실 정보 저장
}
return pq.size(); // 강의실 수 리턴
}

/**
* [강의실 배정]
*
* 강의실 수를 최소로 하기 위해서, 현재 사용하는 강의실 중 가장 빨리 끝나는 강의실에 가장 먼저 시작하는 강의실을 배치해야 한다.
* 이 문제는 모든 강의를 다 진행해야 하므로, 회의실 배정 문제와는 다르다! 먼저 시작하는 순으로 정렬할 것.
* 현재 가장 빨리 끝나는 시간을 구하기 위해 최소 힙(우선순위 큐) 사용
*/

int main() {
int n; // n: 수업 개수

// 입력
cin >> n; // 수업 개수
vector<ci> lec(n, ci(0, 0)); // 수업에 관한 정보를 저장할 vector lec
for (int i = 0; i < n; i++) { // 수업에 관한 내용 vector lec 에 저장
cin >> lec[i].first >> lec[i].second; // first: 시작시간, second: 종료시간
}

// 연산
sort(lec.begin(), lec.end()); // 수업을 먼저 시작하는 순서로 정렬

// 출력
cout << arrayRoom(n, lec) << '\n'; // arrayRoom() 함수를 호출에서 출력
return 0;
}
47 changes: 47 additions & 0 deletions [그리디] 4월 12일/13305_sample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <iostream>
#include <vector>

using namespace std;
typedef long long ll; // long long 자료형을 ll으로 선언

// greedyOil() 함수, 최소비용을 출력
ll greedyOil(vector<pair<ll, ll>> &city, int n) { // 리턴 값: 최소 비용, 입력 값: 도시에 관한 정보, 도시의 개수
ll cur_cost = city[0].second, tot_cost = 0; // cur_cost: 현재의 (가장 저렴한)비용, tot_cost: 총 비용

for (int i = 0; i < n; i++) { // n개의 도시 동안
if (city[i].second < cur_cost) { // 이 도시의 기름값이 더 저렴하면 교체
cur_cost = city[i].second; // 현재의 가격을 더 저렴한 비용으로 교체
}
tot_cost += (cur_cost * city[i].first); // 이동 비용
}
return tot_cost; // 총 비용을 리턴
}

/**
* [주유소]
*
* 최대한 가격이 싼 곳에서 많은 기름을 넣어야 한다.
* 따라서 첫번째 도시부터 현재까지 가장 싼 가격을 저장하고, 이동에 필요한만큼만 기름을 채운다.
* 이렇게 하면 지금까지 지나 온 도시 중 가장 싼 곳에서 최대한 많이 살 수 있다.
*
* !주의! 도시 사이의 간격이 최대 10^9이고, 리터당 가격이 최대 10^9이므로
* 가능한 정답의 최댓값은 10^18으로 int 범위 넘어감! -> long long 써야 함
*/

int main() {
int n; // n: 도시의 개수

// 입력
cin >> n; // 도시의 개수를 입력 받음
vector<pair<ll, ll>> city(n, {0, 0}); // 도시의 관한 정보를 저장할 vector city, x: 도로 수, y: 리터당 가격
for (int i = 0; i < n - 1; i++) { // (도시의 개수-1) 개의 도로 수
cin >> city[i].first; // 도로의 수를 vector city의 첫째 위치에 저장
}
for (int i = 0; i < n; i++) { // 도시의 개수 동안
cin >> city[i].second; // 주요소의 리터당 가격 수를 vector city의 둘째 위치에 저장
}

// 연산 & 출력
cout << greedyOil(city, n); // greedyOil() 함수를 호출하여 연산
return 0;
}
47 changes: 47 additions & 0 deletions [그리디] 4월 12일/2437_sample.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#include <iostream>
#include <algorithm>
#include <vector>

using namespace std;

// findUnmeasurable() 함수, 주어진 저울추들로 측정할 수 없는 무게의 최솟값을 계산하는 함수
int findUnmeasurable(vector<int> &weight) { // 리턴 값: 측정할 수 없는 가장 작은 무게, 입력 값: 추들의 정보
int sum = 0; // 현재 측정가능한 무게 범위 sum, 1씩 증가시키면서 비어있는 값을 확인하기 위해 0으로 초기화
// 측정하고자 하는 무게를 무게가 1인 경우부터 +1 하면서 측정가능한지 확인
for (int i = 0; i < weight.size(); i++) { // 저울추의 개수 동안 반복, 모든 정수 무게를 확인
if (sum + 1 < weight[i]) { // 현재 측정가능한 무게 범위 sum + 1 이 저울추의 무게 보다 작은 경우, 측정 불가한 최솟값이 되므로
return sum + 1; // sum+1 리턴
}
sum += weight[i]; // 측정가능한 범위를 증가
}
return sum + 1; // 저울추 합 이내의 모든 경우가 측정 가능한 경우, 측정가능한 값 sum+1 를 리턴
}

/**
* [저울]
*
* 작은 값부터 측정 가능한지 파악해야 하므로, 오름차순으로 정렬한다.
* 현재 0부터 scope까지 모든 무게를 빠짐없이 측정가능하다고 했을 때, 새로운 무게는 scope + 1보다 작거나 같아야 한다.
* ex) 현재 1~5까지 측정 가능한데, 다음 값이 7인 경우 -> 6은 측정 불가
*
* 만약 이 조건을 만족할 경우, 측정 가능한 범위는 [1, scope + 새로운 무게]로 갱신된다.
* 모든 저울을 살펴봤는데도 비어있는 값이 없으면, scope + 1 리턴
*/

int main() {
int n; // n: 저울추의 개수

// 입력
cin >> n; // 저울추의 개수를 입력 받음
vector<int> weight(n, 0); // 각 저울추의 무게를 정보를 나타내는 vector weight
for (int i = 0; i < n; i++) { // 저울추의 개수 동안
cin >> weight[i]; // 저울추의 무게 저장
}

// 정렬
sort(weight.begin(), weight.end()); // 오름차순 정렬

// 연산 & 출력
cout << findUnmeasurable(weight); // findUnmeasurable() 함수 호출
return 0;
}