A. Contest Start
https://codeforces.com/contest/1539/problem/A
Problem - A - Codeforces
codeforces.com
까다로웠던 A문제.
수평선에
그렇다면 어떤 사람의 좌표
제일 끝에 있는 사람
다시 표현해보면,
...
+
가 답이 되는 줄 알고 제출했다가 못풀었다.
한가지 예외가 있는데,
결국,
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 2147483647;
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
int main() {
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int T;
cin >> T;
while (T--) {
ll n, x, t;
cin >> n >> x >> t;
ll cnt = t / x;
ll ans = min( n * (n - 1), (cnt) * (cnt - 1)) / 2 + max(0LL, cnt * (n - cnt));
cout << ans << '\n';
}
return 0;
}
B. Love Song
https://codeforces.com/contest/1539/problem/B
Problem - B - Codeforces
codeforces.com
구간 합으로 해결했다.
각 알파벳 별로
구간 합을 구하는 과정의 시간 복잡도
구간 합을 통해 q개의 결과를 구하는 시간 복잡도
n과 q의 범위가 같기 때문에 시간 복잡도는
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 2147483647;
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
int dp[27][100001] = { 0 , };
int main() {
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n, q;
string str;
cin >> n >> q >> str;
// 구간 합
for (int i = 1; i <= n; i++) dp[str[i - 1] - 'a' + 1][i]++;
for (int i = 1; i <= 26; i++) {
for (int j = 1; j <= n; j++) {
if(dp[i][j] == 1) dp[i][j] = dp[i][j - 1] + 1;
else dp[i][j] = dp[i][j - 1];
}
}
for (int i = 0; i < q; i++) {
int l, r;
cin >> l >> r;
int ans = 0;
for (int alp = 1; alp <= 26; alp++) {
ans += (dp[alp][r] - dp[alp][l - 1]) * alp;
}
cout << ans << '\n';
}
return 0;
}
C. Stable Groups
https://codeforces.com/contest/1539/problem/C
Problem - C - Codeforces
codeforces.com
두 그룹이 있을 때 몇 명의 학생을 추가해야 한 그룹으로 만들 수 있을까 ?
작은 수가 모인 그룹 1, 큰 수가 모인 그룹 2가 있다고 가정하자.
두 그룹을 묶으려면 그룹 1의 가장 큰 수와 그룹 2의 가장 작은 수의 차에 따라 필요한 학생의 수가 결정된다.
두 수의 차를
인 것으로 보아 필요한 학생 수는
결국 우리가 구해야 할 것은 두 그룹을 묶는데 필요한 학생 수를 구하고, 주어진
나의 풀이법은 처음
이후 정렬된 학생들의 차를 구하여 배열
이제
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 2147483647;
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
ll a[200001] = { 0, };
ll dif[200001] = { 0, };
int main() {
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
ll n, k, x, tmp;
cin >> n >> k >> x;
for (int i = 0; i < n; i++) cin >> a[i];
sort(a, a + n);
for (int i = 1; i < n; i++) dif[i - 1] = max(0LL ,(a[i] - a[i - 1] - 1LL) / x);
sort(dif, dif + n - 1);
ll ans = n;
for (int i = 0; i < n - 1; i++) {
if (k >= dif[i]) {
k -= dif[i];
ans--;
}
}
cout << ans << '\n';
return 0;
}
D. PriceFixed
https://codeforces.com/contest/1539/problem/D
Problem - D - Codeforces
codeforces.com
핵심은 할인을 최대한 많이 받으면서 물건을 구매해야한다. 그렇다면 할인받는데 필요한 구매 개수가 각각 2, 8개인 물건이 있다고 가정하자. 어떤 물건부터 사는게 할인에 유리할까 ? 당연히 8개를 사야 할인 받을 수 있는 물건을 먼저 사고 2개 짜리를 할인 받는게 유리할 것이다. 이 아이디어가 맞다면 투 포인터로 해결할 수 있을 것이다.
할인받는데 필요한 구매 개수를
포인터 하나는 배열의 가장 앞, 다른 하나는 가장 뒤로 설정하고 while문으로 출발해보자.
while문에서 할 일은 간단하다. 앞에 있는 상품을 할인 받을 수 있을 만큼 뒤에서부터 물건을 구매한다. 뒤쪽 물건 구매가 끝나면, 앞쪽으로 넘어와서 할인받을 수 있는 물건들은 모조리 다 사버린다. 더이상 할인을 받을 수 없다면, while문 처음으로 돌아가 같은 과정을 반복한다.
투포인터로 해결하기 때문에 시간복잡도는
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int INF = 2147483647;
ll gcd(ll a, ll b) { for (; b; a %= b, swap(a, b)); return a; }
pair<ll, ll> p[100001] = { {0, 0}, };
int main() {
ios::ios_base::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int n;
cin >> n;
for (int i = 0; i < n; i++) cin >> p[i].second >> p[i].first;
sort(p, p + n);
int start = 0, end = n - 1;
ll buy = 0; // 지금까지 구매한 물건의 수
ll ans = 0;
while (start <= end) {
ll least = p[start].first; // 이만큼 사야한다.
for (end; end >= start; end--) {
if (buy + p[end].second < least) { // p[end]에 있는 물건을 다 사야하는 경우
ans += 2 * p[end].second;
buy += p[end].second;
p[end].second = 0;
}
else { // p[end]에 있는 물건 몇개만 사도 되는 경우
p[end].second -= (least - buy);
ans += 2 * (least - buy);
buy = least;
break; // 아직 p[end]에 있는 물건을 다 사지 않았기 때문에
// break문을 통해 end 유지
}
}
while (start <= end && p[start].first <= buy) { // 할인 받을 수 있는동안
ans += p[start].second;
buy += p[start].second;
start++;
}
}
cout << ans;
return 0;
}
'codeforce' 카테고리의 다른 글
Round #731 (Div. 3) (0) | 2021.07.11 |
---|---|
Round #728 (0) | 2021.06.26 |
Round #725 (Div. 3) (0) | 2021.06.14 |
Round #707 (Div. 2) (0) | 2021.05.25 |
Round #706 (Div. 2) (0) | 2021.05.24 |