PS/Codeforces

[Codeforces] Round 800 Div.2 인생 첫 코포 후기

kth990303 2022. 6. 21. 21:58
반응형

얼마 전에 인생 첫 코포를 응시해봤다. 처음 6판은 배치고사라고 한다. AB 또는 ABC를 풀 수 있지 않을까? 기대해봤지만...

두 예측 모두 틀렸다. A, C로 2솔했다ㅋㅋ 개인적으로 첫 코포 목표를 달성해서 좋았고, +468점이나 올라서 좋았다.

초록색, 또는 민트색 달 때까지는 꾸준히 한번 돌려봐야겠다.

 

백준이랑 다른 스타일이었다. 백준 대회 (ex. UCPC 등)들은 여러 알고리즘들을 골고루 물어본다면, 코포는 애드혹과 수학, 아이디어 쪽에 치중된 느낌? 개인적으로는 두 스타일 모두 좋다고 생각하며, 코포 스타일이 재밌을 때도 있고 백준대회 스타일이 재밌을 때도 있는 듯.

 

개인적으론 B가 정말 특수한 아이디어 쪽이었어서 나한테는 정말 어려웠다. B에 시간 쫓겨서 A만 1솔할 줄 알았는데, 막판에 C 보고 대회 30초 남기고 바로 제출해서 2솔이 되었다. C가 B보다 훨씬 쉬운 느낌이었는데... B 문제를 잘 기억해둬야겠다.

 

다행히 ps톡방들을 보니 나만 B가 어려운 것이 아니었다.

A만 1솔하신 분들도 많았고, 나처럼 AC 또는 AD 푸신 분들이 많았다.

이건 고수분들에게 B가 쉬웠기 때문에 문제위치 선정이 이렇게 된 것인데, 한 번 B번 문제를 철저하게 복기해봐야겠다.

 

문제 목록은 여기서 볼 수 있다.

https://codeforces.com/contest/1694

 

Dashboard - Codeforces Round #800 (Div. 2) - Codeforces

 

codeforces.com


A. Creep

문제 이해가 좀 어려웠는데, 각 구간의 creepiness의 최대값을 최소화시키는 문제이다. (이렇게 번역하니까 이분탐색 문제처럼 들린다..)

일단 min(a, b)까지는 무조건 1과 0이 필수적으로 나오긴 해야 한다. 따라서 1과 0을 번갈아가면서 출력해주는 것이 creepiness를 최소화하는 방법이다. 그 외에는 어쩔 수 없이 creepiness가 증가할 수밖에 없으므로 max(a,b)-min(a,b)만큼 남은 숫자를 출력해준다.

#include <bits/stdc++.h>
#define sz(v) (int)v.size()
#define all(v) (v).begin(), (v).end()
#define press(v) (v).erase(unique(all(v)), (v).end())
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<int,pi> pii;
typedef pair<ll, ll> pl;
const int MAX = 1e5+7;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
int t,a,b;
int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin>>t;
    while(t--){
        cin>>a>>b;
        cout<<"10";
        --a;--b;
        int M=max(a,b);
        int m=min(a,b);
        if(a>=b){
            for(int i=0;i<m;i++){
                cout<<"01";
            }
            for (int i = 0; i < M-m; i++) {
                cout<<0;
            }
        }
        else{
            for(int i=0;i<m;i++){
                cout<<"10";
            }
            for (int i = 0; i < M-m; i++) {
                cout<<1;
            }
        }
        cout<<"\n";
    }
}

C. Directional Increase

먼저, 무조건 원점으로 돌아와야 하므로 각 값의 합이 0이어야 한다.

그리고 중간에 누적합 값이 0 이하가 나와버린다는 것은 왼쪽으로 원점보다 많이 이동하지 않는 이상 불가능하므로 이 경우에도 답이 No.

#include <bits/stdc++.h>
#define sz(v) (int)v.size()
#define all(v) (v).begin(), (v).end()
#define press(v) (v).erase(unique(all(v)), (v).end())
using namespace std;
typedef long long ll;
typedef pair<int, int> pi;
typedef pair<int,pi> pii;
typedef pair<ll, ll> pl;
const int MAX = 2e5+7;
const int INF = 0x3f3f3f3f;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int MOD = 1e9 + 7;
ll t,N,a[MAX],p[MAX];
int main() {
    cin.tie(0)->sync_with_stdio(0);
    cin>>t;
    while(t--){
        cin>>N;
        ll sum=0,idx=0;
        for(int i=1;i<=N;i++){
            cin>>a[i];
            sum+=a[i];
            p[i]=p[i-1]+a[i];
            if(a[i])idx=i;
        }
        if(sum){
            cout<<"No\n";
            continue;
        }
        bool flag=true;
        int k=0;
        for (int i = 1; i <= N; i++) {
            if(i<idx&&p[i]==0){
                flag=false;
                break;
            }
            if(p[i]<0){
                flag=false;
                break;
            }
        }
        cout<<(flag?"Yes\n":"No\n");
    }
}

 


아래부터는 업솔빙

B. Paranoid String

처음에는 케이스 분류 노가다 문제인 줄 알았다. 
01 -> 1 / 10 -> 0으로 바뀌는 걸 캐치해서 00001과 같이 값이 바뀌는 경우는 paranoid string임을 캐치했다. 그러나, 0010001과 같은 경우는 001/1 -> 1/1 에서 더 나아가지 못한다 생각해서 paranoid string이 되는 줄 몰랐다.
그러다 어느 순간, 0010001 -> 0010/1 -> 0001 -> 1 로 해서 paranoid string이 될 수 있다는 것을 캐치했다. 여기서부터 나는 케이스 분류 노가다 문제이구나 생각하게 됐던 것이다.
알고 보니, s[i]!=s[i-1]일 때엔 그 앞을 항상 paranoid로 만들 수 있다는 점을 생각했다면 접근할 수 있는 문제였다. 0010001에서 001은 무조건 s[i]!=s[i-1]부분까진 paranoid string 이다. 0010도 paranoid string이다. 0001도 paranoid string이다. 이렇게 10 -> 0 / 01 -> 1처럼 무조건 두 번째 숫자로 바뀌는 법칙 때문에 위 성질이 성립하게 된다.
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll t,n;
string s;
int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin>>t;
	while(t--){
		cin>>n>>s;
		ll ans=n;
		for(ll i=1;i<n;i++){
			if(s[i]!=s[i-1])ans+=i;
		}
		cout<<ans<<"\n";
	}
}

결과

배치고사 첫 판이라 점수를 후하게 받았다.

 

다음 목표는 2솔을 좀 더 빠르게 하는 것이다.

막히는 문제가 있으면 빠르게 넘기는 습관을 들여야겠다. 그리고 어떠한 문제가 어렵고 쉬운지 분별하는 능력도 길러봐야겠다.

반응형

'PS > Codeforces' 카테고리의 다른 글

[Codeforces] Round #757 (Div. 2) A~C 풀이 및 후기  (0) 2021.11.30