A 문제
문제는 매우 간단합니다. 세 정수 r, g, b와 문자열 c가 주어집니다. c가 "Red"이면 g와 b 중 최솟값을, "Blue"이면 r와 g 중 최솟값을, 그 외의 경우 r와 b 중 최솟값을 출력하면 됩니다.
코드 보기
#include<bits/stdc++.h>
using namespace std;
int main(){
int red, green, blue;
string color;
cin >> red >> green >> blue >> color;
if(color == "Red"){
cout << min(green, blue);
} else if(color == "Blue"){
cout << min(red, green);
} else {
cout << min(red, blue);
}
return 0;
}
B 문제
세 점의 좌표가 주어졌을 때, 이들이 직각삼각형을 이루는지 판별하는 문제입니다. 먼저 세 점 사이의 거리를 각각 구하고, 가장 긴 변을 빗변으로 가정합니다. 피타고라스 정리에 따라 나머지 두 변의 제곱합이 빗변의 제곱과 일치하면 직각삼각형입니다. double형 연산에서는 오차가 발생할 수 있으므로, 차이가 1e-6 미만이면 같다고 판단합니다.
코드 보기
#include<bits/stdc++.h>
using namespace std;
struct Point {
int x, y;
};
double calculateDistance(Point p1, Point p2){
long long dx = p1.x - p2.x;
long long dy = p1.y - p2.y;
return sqrt((double)dx*dx + (double)dy*dy);
}
int main(){
Point p[3];
for(int i = 0; i < 3; ++i){
cin >> p[i].x >> p[i].y;
}
double sides[3];
sides[0] = calculateDistance(p[0], p[1]);
sides[1] = calculateDistance(p[0], p[2]);
sides[2] = calculateDistance(p[1], p[2]);
sort(sides, sides + 3);
double hypotenuse = sides[2];
double leg1 = sides[0];
double leg2 = sides[1];
double left = leg1*leg1 + leg2*leg2;
double right = hypotenuse*hypotenuse;
if(fabs(left - right) < 1e-6){
cout << "Yes";
} else {
cout << "No";
}
return 0;
}
C 문제
n개의 구간 [l_i, r_i]가 주어집니다. 각 구간에서 하나의 정수 a_i를 선택하여, 전체 합이 0이 되도록 하는 문제를 해결합니다. 먼저 모든 l_i의 합을 L, 모든 r_i의 합을 R라 하면, 합이 0이 가능하려면 L ≤ 0 ≤ R를 만족해야 합니다. 가능하다면, 초기값을 모두 l_i로 설정하고 합이 0이 될 때까지 차근차근 값을 늘려갑니다.
코드 보기
#include<bits/stdc++.h>
using namespace std;
int main(){
int n;
cin >> n;
vector<long long> left(n+1), right(n+1), answer(n+1);
long long sumLeft = 0, sumRight = 0;
for(int i = 1; i <= n; ++i){
cin >> left[i] >> right[i];
sumLeft += left[i];
sumRight += right[i];
answer[i] = left[i];
}
if(!(sumLeft <= 0 && sumRight >= 0)){
cout << "No";
return 0;
}
cout << "Yes" << '\n';
long long needed = -sumLeft;
for(int i = 1; i <= n && needed > 0; ++i){
long long canIncrease = right[i] - left[i];
if(needed >= canIncrease){
answer[i] = right[i];
needed -= canIncrease;
} else {
answer[i] += needed;
needed = 0;
}
}
for(int i = 1; i <= n; ++i){
cout << answer[i] << " ";
}
return 0;
}
D 문제
이 문제는 가중치가 있는 그래프에서 최단 경로를 찾는 문제입니다. 각 정점에는 a_i라는 점수가 있고, 간선을 통과할 때 도착 정도의 점수를 간선 가중치에 포함시키면 됩니다. 즉, u에서 v로 가는 실제 비용은 w + a[v]가 됩니다. 다익스트라 알고리즘을 사용하여 1번 정점에서 다른 모든 정점까지의 최소 비용을 구하면 됩니다.
코드 보기
#include<bits/stdc++.h>
using namespace std;
struct Edge {
int to;
long long weight;
};
int main(){
int vertex, edges;
cin >> vertex >> edges;
vector<long long> nodeValue(vertex + 1);
for(int i = 1; i <= vertex; ++i){
cin >> nodeValue[i];
}
vector<vector<Edge>> graph(vertex + 1);
for(int i = 0; i < edges; ++i){
int u, v, w;
cin >> u >> v >> w;
graph[u].push_back({v, w + nodeValue[v]});
graph[v].push_back({u, w + nodeValue[u]});
}
const long long INF = 1e18;
vector<long long> dist(vertex + 1, INF);
vector<bool> visited(vertex + 1, false);
dist[1] = nodeValue[1];
priority_queue<pair<long long,int>,
vector<pair<long long,int>>,
greater<pair<long long,int>>> pq;
pq.push({dist[1], 1});
while(!pq.empty()){
auto [d, cur] = pq.top();
pq.pop();
if(visited[cur]) continue;
visited[cur] = true;
for(const auto& e : graph[cur]){
int next = e.to;
long long cost = e.weight;
if(dist[next] > dist[cur] + cost){
dist[next] = dist[cur] + cost;
pq.push({dist[next], next});
}
}
}
for(int i = 2; i <= vertex; ++i){
cout << dist[i] << " ";
}
return 0;
}