요즘 너무 바쁘다.
게임 엔진 건드릴 시간이 없다...
아무튼, shake 2021의 문제를 풀어봤습니다.
Open Contest에서는 D번까지 풀었고, 그 뒤로는... 나중에 풀어봐야겠습니다.
시간이 부족행
BOJ 24228. 젓가락
문제 링크 : https://www.acmicpc.net/problem/24228
24228번: 젓가락
두 개의 정수 N,R이 주어진다. (1≤N,R≤1018)
www.acmicpc.net
풀이 : 젓가락이 한 쌍 완성되기 위한 최악의 경우는,
모든 젓가락을 하나씩 뽑은 뒤에 아무 젓가락이나 하나 뽑는 경우입니다. 이 때 뽑는 갯수는 N+1개입니다.
그 이후엔 방금 완성한 한 쌍을 다시 뽑는 경우 (2개)와, 나머지 젓가락 중 한 쌍을 완성하는 경우 (1개)로 나뉩니다.
다시 말해서 최악의 경우는 모든 젓가락을 하나씩 뽑고, 그 이후로는 특정 젓가락만을 계속 뽑는 경우가 됩니다.
따라서 처음 한 쌍을 완성하기 위한 N+1개, 그 이후로 R−1개의 쌍을 완성하기 위한 2×(R−1)개를 뽑아야 하므로, N+2R−1을 출력하면 됩니다.
N,R의 범위가 1018이므로, long long을 사용해야 합니다.
#include <iostream>
#include <algorithm>
using namespace std;
long long N, R;
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N >> R;
cout << N + 2 * R - 1;
return 0;
}
BOJ 24229. 모두싸인 출근길
문제 링크 : https://www.acmicpc.net/problem/24229
24229번: 모두싸인 출근길
취준생 주헌이는 드디어 취업에 성공했다. 주헌이가 취직한 회사는 비대면 전자계약 서비스 모두싸인(MODUSIGN) 이라는 회사이다. 그리고 오늘은 첫 출근날이다. 주헌이의 출근길에는 다리가 있
www.acmicpc.net
풀이 : N≤200000이므로, 간단하게 왼쪽부터 해당 판자에서 이동할 수 있는 최대 거리를 계산해 나가면 됩니다.
편의를 위해 연결된 판자는 모두 하나로 합치고, 해당 판자에 도달할 수 없다면 탐색을 멈추면 됩니다.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef pair<int, int> p;
const int MAX = 1e9 + 5;
int N, ans;
p line[200001];
vector<p> v;
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N;
for (int i = 0; i < N; i++) cin >> line[i].first >> line[i].second;
sort(line, line + N);
v.push_back(line[0]);
for (int i = 1; i < N; i++)
if (v.back().second >= line[i].first)
v.back().second = max(v.back().second, line[i].second);
else
v.push_back(line[i]);
N = v.size();
for (int i = 0; i < N && i <= ans; i++)
{
p P = { v[i].second * 2 - v[i].first, MAX };
auto it = upper_bound(v.begin(), v.end(), P);
it--;
ans = max(ans, (int)(it - v.begin()));
}
cout << v[ans].second;
return 0;
}
24230. 트리 색칠하기
문제 링크 : https://www.acmicpc.net/problem/24230
24230번: 트리 색칠하기
정점이 N개인 트리가 있다. 정점에는 1부터 N까지 번호가 붙어있다. 트리의 루트는 항상 1번 정점이며 맨 처음에는 모든 정점이 하얀색으로 칠해져 있는 상태이다. 하나의 정점에 색칠하면 해
www.acmicpc.net
풀이 : 부모 노드가 색칠되면, 자식 노드도 모두 색칠됩니다.
따라서 부모 노드를 먼저 색칠한 뒤에, 자식 노드를 색칠해야 합니다.
부모 노드부터 그래프 탐색을 시작해서, 부모 노드와 자식 노드의 색이 다르다면 횟수를 1 올리고
그 자식 노드에 대해서 그래프 탐색을 실행하면 됩니다.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int N, color[200001], a, b;
vector<int> graph[200001];
bool v[200001];
int dfs(int node, int c)
{
int ret = color[node] != c;
v[node] = 1;
for (int& adj : graph[node])
if (!v[adj]) ret += dfs(adj, color[node]);
return ret;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cin >> N;
for (int i = 1; i <= N; i++) cin >> color[i];
for (int i = 1; i < N; i++)
{
cin >> a >> b;
graph[a].push_back(b);
graph[b].push_back(a);
}
cout << dfs(1, 0);
return 0;
}
24231. 해석
문제 링크 : https://www.acmicpc.net/problem/24231
24231번: 해석
(와 )로만 이루어진 문자열을 괄호 문자열이라고 한다. 괄호 문자열 중, 다음 규칙을 지키는 문자열을 올바른 괄호 문자열이라고 한다. 빈 문자열은 올바른 괄호 문자열이다. A가 올바른 괄
www.acmicpc.net
풀이 : 구간 [L,R]에 존재하는 문자열의 갯수를 생각해봅시다.
L<i<R인 S[L]≠S[i]를 만족하는 모든 i에 대한 구간 [L+1,i−1]의 문자열 갯수 * [i+1,R]의 문자열 갯수를 더하면 됩니다.
점화식으로 나타내면 다음과 같습니다.
C[L,R]=∑L<i<RC[L+1,i−1]×C[i+1,R]
갯수를 곱하므로, 빈 문자열의 경우 (L≥R)엔 1을 반환해야 합니다.
모듈러 연산을 하긴 하지만, 점화식에서 곱이 최대 1018 정도까지 나올 수 있어서, long long을 사용했습니다.
그리고 연산 횟수가 많아 시간 초과가 날 수 있으므로, 메모이제이션 등을 사용해서 이미 구한 구간은 넘어갈 수 있도록 처리해줘야 합니다. 계산하지 않은 경우엔 -1, 계산한 경우엔 0부터 시작하도록 처리했습니다.
참고로 문자열의 길이가 홀수라면 올바른 문자열이 존재할 수 없습니다.
처음부터 길이가 홀수라면 바로 0을 출력하면 되고, 점화식을 계산할 때 i를 2씩 증가시켜도 됩니다.
#include <iostream>
#include <algorithm>
#include <string>
#include <string.h>
using namespace std;
typedef long long ll;
const int MOD = 1e9 + 7;
string S;
ll d[301][301];
ll getCount(int L, int R)
{
if (L >= R) return 1;
ll& ret = d[L][R];
if (ret >= 0) return ret;
ret = 0;
for (int i = L + 1; i <= R; i += 2)
if (S[L] != S[i]) ret = (ret + getCount(L + 1, i - 1) * getCount(i + 1, R)) % MOD;
return ret;
}
int main()
{
ios_base::sync_with_stdio(0);
cin.tie(0);
memset(d, -1, sizeof(d));
cin >> S;
if (S.size() % 2) cout << 0;
else
cout << getCount(0, S.size() - 1);
return 0;
}
E번부터는 언젠가 시도해보고, 되면 관련 포스팅을 새로 올리겠습니다.
근데 아마 안 해볼 것 같음 ㅋㅋ;
p.s. 2022.03.12 추가) 아니 이걸 풀었네 ㅋㅋ
'C++ > PS' 카테고리의 다른 글
[Theory] Slope Trick (함수 개형을 이용한 최적화) (1) | 2024.06.26 |
---|---|
[BOJ/C++] shake! 2021 E ~ I번 (BOJ 24232, 24233, 24234, 24235, 24236) (0) | 2022.03.12 |
[BOJ/C++] 23744. 알고리즘 과외 (0) | 2022.01.05 |
[BOJ/C++] 17476. 수열과 쿼리 28 (0) | 2021.12.27 |
[BOJ/C++] 13263. 나무 자르기 (0) | 2021.12.22 |