자료구조&알고리즘
[알고리즘 연습] 2021년도 11월 첫째주 학습 (D번 문제 풀이)
초코쨔응
2021. 12. 6. 23:26
AtCoder Beginner Contest 227 (D번 문제): 이분탐색
Codeforces Round #753 (Div.3) (D번 문제): 그리디
대회를 진행할 때 D번 문제에서 대부분 막혀서, 풀지 못한 D번 문제들을 기록해두고자 한다.
1. AtCoder Beginner Contest 227 (D번 문제)
문제
https://atcoder.jp/contests/abc227/tasks/abc227_d
N 개의 부서에 Ai명의 직원들이 있는데, K 개의 다른 부서에서 K 명을 뽑아오려고 한다. 이렇게 뽑았을 때 만들 수 있는 project의 최대 개수를 구해야한다.
입력
3 3
2 3 4
정답
2
풀이
https://atcoder.jp/contests/abc227/editorial/2919
이분 탐색
코드
#include <bits/stdc++.h>
using namespace std;
int main(){
int n, k; cin >> n >> k;
vector<long long> v(n);
for(long long &x : v) cin >> x;
long long ok = 0, ng = 1e18 / k;
while(ng - ok > 1){
long long md = (ok + ng) / 2, sum = 0;
for(long long x : v) sum += min(x, md);
if(sum >= k * md) ok = md;
else ng = md;
}
cout << ok << endl;
}
2. Codeforces Round #753 (D번 문제)
문제
https://codeforces.com/contest/1607/problem/D
숫자들마다 파란색인지 빨간색인지를 정해주고, 매번 아래의 동작 중 하나를 선택한다.
- either you can select any blue element and decrease its value by 1 (파란 숫자 1 빼기)
- or you can select any red element and increase its value by 1 (빨간 숫자 1 더하기)
숫자들을 1부터 n 까지의 순열로 만들 수 있는지 가능 여부를 출력한다.
입력
8
4
1 2 5 2
BRBR
2
1 1
BB
5
3 1 4 2 5
RBRRB
5
3 1 3 1 3
RBRRB
5
5 1 5 1 5
RBRRB
4
2 2 2 2
BRBR
2
1 -2
BR
4
-2 -1 4 0
RRRR
출력
YES
NO
YES
YES
NO
YES
YES
YES
풀이 & 코드
https://codeforces.com/contest/1607/submission/134073147
#include <bits/stdc++.h>
#define int long long
using namespace std;
vector <int> v;
int a[1000005];
signed main(int argc, char** argv) {
ios::sync_with_stdio(false);
cin.tie(0);
int T;
cin >> T;
while(T--)
{
int n;
cin >> n;
for(int i=1;i<=n;i++)
cin >> a[i];
string s;
v.clear();
cin >> s;
s=' '+s;
for(int i=1;i<=n;i++)
{
if(s[i]=='B') v.push_back(a[i]);
}
sort(v.begin(),v.end());
int flag=1;
for(int i=0;i<v.size();i++)
if(v[i]<=i) flag=0;
v.clear();
for(int i=1;i<=n;i++)
{
if(s[i]=='R') v.push_back(a[i]);
}
sort(v.begin(),v.end());
int now=n;
for(int i=(int)v.size()-1;i>=0;i--)
{
if(v[i]>now) flag=0;
--now;
}
if(flag)
{
cout << "YES\n";
}
else cout << "NO\n";
}
return 0;
}
https://codeforces.com/contest/1607/submission/134082713
void solve() {
int n; cin >> n;
vector <int> v(n); cin >> v;
vector <int> r, b;
for (int i = 0; i < n; i++) {
char c; cin >> c;
if (c == 'R') r.push_back(v[i]);
else b.push_back(v[i]);
}
sort(rall(r));
sort(all(b));
for (int i = 0; i < r.size(); i++) {
if (r[i] > n - i) {
cout << "NO";
return;
}
}
for (int i = 0; i < b.size(); i++) {
if (b[i] < i + 1) {
cout << "NO";
return;
}
}
cout << "YES";
}
이 방법이 반례가 없는 풀이 방법이 맞는 것일까?