아 진짜 아쉽네요 E에서 뭐가 틀린 건지 한참 헤멨는데 int를 long long으로 바꾸니까 바로 AC 받았습니다.

그것만 신경 써줬으면 1350 정도 퍼포 나왔을텐데 진짜 아쉽네요..

 

세네판 정도 안에 그린 찍고 싶었는데 ㅋㅋ 안 될 것 같네요

 

A. Print a Pedestal (Codeforces logo?)

가운데가 제일 길쭉하고 왼쪽이 그 다음, 오른쪽이 그다음으로 길도록 해주는 단순 구현 문제입니다.

#include <stdio.h>

int main() {
int n, t;
scanf("%d", &t);
while(t--) {
    scanf("%d", &n);
    int first = n / 3 + 1;
    if(n % 3 != 0) first++;
    int second = n - first;
    second /= 2;
    second++;
    int third = n - first - second;
    printf("%d %d %d\n", second, first, third);
}
}

 

B. Array Decrements

이번 코포는 B 때문에 망했다고 해도 과언이 아닌..

#include <stdio.h>

int main() {
int n,m, t;
int arr[1000000] = {};
int brr[1000000] = {};
scanf("%d", &t);
while(t--) {
    scanf("%d", &n);
    int temp = 0,NO = 0,no = 0;
    for(int i = 0; i < n; i++) {
        scanf("%d", &arr[i]);
    }
    for(int i = 0; i < n; i++) {
        scanf("%d", &brr[i]);
        if(arr[i] < brr[i]) NO = 1;
    }
    for(int i = 0; i < n; i++) {
            if(temp < arr[i] - brr[i]) temp = arr[i] - brr[i];
    }
    if(temp == 0) temp = arr[0] - brr[0];
    for(int i = 0; i < n; i++) {
        arr[i] -= temp;
    }
    for(int i = 0; i < n; i++) {
        if(arr[i] != brr[i]) {
            no++;
            if(brr[i] == 0 && arr[i] <= 0) no--;
        }
    }
    if(no || NO) printf("NO\n");
    else printf("YES\n");
}
}

이렇게 어렵게 푸는 것도 맞는지도 모르겠습니다 사실..

여태 코포 몇판 안 해봤지만 중간에 문제 하나 막히면 거기서 말리기 시작하는 타입인 거 같아요 저는

 

C. Restoring the Duration of Tasks
 

일 끝나기 전에 다음 task 주면, task 끝낸 시간의 간격 출력.

일 끝나고 난 후에 다음 task 주면 task 준 시간과 끝낸 시간의 간격 출력.

푸는 데에 5분도 안 걸렸습니다.

#include <stdio.h>
int main() {
int n, t;
long long arr[300000] = {};
long long brr[300000] = {};
scanf("%d", &t);
while(t--) {
    scanf("%d", &n);
    for(int i = 0; i < n; i++) {scanf("%lld", &arr[i]);
    }
    for(int i = 0; i < n; i++) {scanf("%lld", &brr[i]);
    }
    printf("%lld ", brr[0] - arr[0]);
    for(int i = 1; i < n; i++) {
        if(arr[i] < brr[i - 1]) printf("%lld ", brr[i] - brr[i - 1]);
        else printf("%lld ", brr[i] - arr[i]);
    }
    printf("\n");
}
}

D. Black and White Stripe

 

문자열에서 0~k-1 의 문자열 안에 W가 얼마나 들어있는지 찾고

앞으로 한 칸씩 나가면서 가장 적은 값 출력.

엄청 쉬운 문제인데 구현 실수해서 2번이나 틀렸습니다.

근데 이건 제 실력이 부족한 탓이에요

#include <stdio.h>
#include <algorithm>

int main() {
int n,m, t;
char s[300000] = {};
scanf("%d", &t);
while(t--) {
 scanf("%d", &n);
 scanf("%d", &m);
 scanf("%s", s);
 int count = 0, min = 10000000;
 for(int i = 0; i < m; i++) {
     if(s[i] == 'W') count++;
 }
 if (min > count) min = count;
 for(int i = 0; i < n - m; i++) {
     if(s[m + i] == 'W') count++;
     if(s[i] == 'W') count--;
     if(min > count) min = count;
 }
 printf("%d\n", min);
}
}

E. Price Maximization

 

맨 처음에 각각 물건 입력받으면서 k로 나눈 값 더해주고,

나머지는 모아서 배열에 담은 다음에 작은놈들끼리 짝지어주면서 짝 맞으면 더해주는 식으로 짰습니다...

 

구현까지도 괜찮았는데 long long을 쓰는 걸 깜빡했네요

𝑎𝑛은 10억까지도 가능하니까 당연히 long long인데 이걸 뭔 생각으로 int로 출력하려 했는지..  앞으로 

#define int long long 쓰겠습니다 짜증나서..

#include <stdio.h>

int main() {
int n,m, t;
int k[1001] = {};
scanf("%d", &t);
while(t--) {
    scanf("%d%d", &n, &m);
    long long temp = 0;
    long long ans = 0;
    for(int i = 0; i < n; i++) {
        scanf("%lld", &temp);
        ans += temp / m;
        k[temp % m]++;
    }

    int end = m, first = 1;
    
    for(int i = 0; i <= m; i++) {
        for(int j = m - i; j <= m; j++) {
                if(i == j) {
                    ans+= k[i] / 2;
                    k[i] %= 2;
                    continue;
                }
                if(k[i] > 0 && k[j] > 0) {
                if(k[i] > k[j]) {
                    int temp = k[j];
                        ans += k[j];
                    k[i] -= temp;
                    k[j] -= temp;
                }
                else {
                    int temp = k[i];
                    ans += k[i];
                    k[i] -= temp;
                    k[j] -= temp;
                }
                                    //printf("%d %d\n", k[i], k[j]);
            }
        }
    }
    for(int i = 0; i < 1000; i++) {
        k[i] = 0;
    }
    printf("%lld\n" , ans);
}
}

 

https://codeforces.com/contest/1681/problem/A

 

Problem - A - Codeforces

 

codeforces.com

3솔 했습니다.

 

A. Game with Cards

 

각자 카드를 번갈아서 내는데, 방금 상대방이 낸 것보다 숫자가 큰 카드를 내야합니다.

Alice가 먼저 카드를 내면 누가 이기는지, Bob이 먼저 카드를 내면 누가 이기는지 출력해주면 됩니다.

 

각자 제일 큰 카드의 값이 같다면, 먼저 내는 애가 이기고(더 큰 카드를 낼 수 없으니까)

아니라면 상대방보다 더 큰 카드를 갖고 있는 애가 무조건 이깁니다.

 

 

B. Card Trick

 

카드 뭉치 위에서 b장을 뽑아서 밑으로 내리는 작업을 m번 했을 때, 가장 위에 오는 카드의 번호를 출력하는 문제입니다.

배열로 카드 원소를 각각 입력받고, 밑으로 내리는 카드 b장을 다 더해서 카드의 총 장수로 나머지 연산을 하면 됩니다.

 ex) [1,2,3,4,5] 5장이라고 가정, 위에서부터 2, 3, 2개 내리는 작업을 했다면 7 % 5 => 2, arr[2] = 3 이런 식입니다.

#include <stdio.h>

int main() {
    int t;
    scanf("%d", &t);
    int arr[300000] = {}, brr[300000] = {};
    while(t--) {
        int n, m;
        int alice = 0, bob = 0;
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%d", &arr[i]);
        }
        scanf("%d", &m);
        int temp, sum = 0;
        for(int i = 0; i< m ; i++) {
            scanf("%d", &temp);
            sum += temp;
            while(sum >= n) {
                sum -= n;
            }
        }
        printf("%d\n", arr[sum]);
    }
}

 

C. Double Sort

 

이거는 2행짜리 배열에서 i열, j열을 골라서 값을 바꿀 때,

각 행이 non-decreasing 하게 정렬이 될 수 있는지,

된다면 몇번 바꿔야 하는지, 그리고 그 바꿀 때의 i와 j를 출력해줘야 하고,

못 바꾸거나 바꿔야하는 횟수가 1만회 넘어가면 -1 출력.

 

이건 그냥 구현입니다.

이중 for문에서

arr[i] > arr[j] && brr[i] < brr[j] 인 경우나

arr[i] < arr[j] && brr[i] > brr[j] 인 경우가 한 개라도 있으면 -1 출력.

아니라면 arr기준으로 먼저 정렬해주고 그 다음에 brr 기준으로 정렬 해줬습니다.

값이 중복될 경우 정렬이 안 될 수 있기에 나눠서 두번 해줬습니다.

ex)

arr [1,1,1,1,1]

brr[5,4,3,2,1]  인 경우 arr만 정렬하거나 혹은 거꾸로인데 brr만 정렬하면 정렬이 안되니까... 

 

A. Log Chopping

둘이서 번갈아가며 나무를 두 조각으로 자르는데, 자기 턴에 나무를 못 자르면 집니다.

나무는 자연수로만 자를 수 있고, 길이가 1이 되면 자르지 못합니다.

누가 나무 자르기 게임에서 이기는지 출력하는 문제입니다.

 

나무의 길이 - 1 횟수만큼 자를 수 있으니, 길이 - 1을 모두 더합니다.

그 값이 홀수면 첫 번째로 자르는 애가, 짝수면  두 번째로 자르는 애가 이깁니다.

#include <stdio.h>
int main() {
    int t;
    scanf("%d", &t);
    for(int p = 0; p < t; p++) {
        int n, temp, sum = 0;
        scanf("%d", &n);
        for(int i = 0; i < n; i++) {
            scanf("%d", &temp);
            sum += temp - 1;
        }
        if(sum % 2 == 1) printf("errorgorn\n");
        else printf("maomao90\n");
    }
}

 

B. I love AAAB

https://codeforces.com/contest/1672/problem/B

 

Problem - B - Codeforces

 

codeforces.com

 

A(개수 무제한)B(무조건 한 개)의 문자열을 순서 상관없이 입력해서 input으로 준 문자열을 만들 수 있는지 체크하는 문제입니다.

 

예를 들어 AAABBAAAB를 만들어봅시다.

빨간색이 추가해준 문자열입니다.

AAAAB -> AABAAAB -> AAABBAAAB == AAABBAAAB.

이런 식으로 막무가내로 끼워넣기도 가능합니다.

 

1. 문자열 시작은 A, 끝은 B

2. 여태 나온 A 개수보다 B 개수가 더 많으면 안 된다. ex> AABBBAAAB (5번째에서 A 둘, B 셋으로 안 됨)

 

충족하면 YES 아님 NO

#include <stdio.h>
#include <string.h>
int main() {
    int t;
    char s[200001] = {};
    scanf("%d", &t);
    for(int p = 0; p < t; p++) {
        int n, temp = 0, sum = 0, no = 0;
        scanf("%s", s);
        for(int i = 0; i < strlen(s); i++) {
            if(s[i] == 'B') sum++;
            if(s[i] == 'A') temp++;
                if(sum > temp) no = 1;
        }
        if(s[strlen(s) - 1] == 'A') no = 1;
        if(no) printf("NO\n");
        else printf("YES\n");
    }
}

 

C. Unequal Array

https://codeforces.com/contest/1672/problem/C

 

Problem - C - Codeforces

 

codeforces.com

You are given an array 𝑎a of length 𝑛n. We define the equality of the array as the number of indices 1𝑖𝑛11≤i≤n−1 such that 𝑎𝑖=𝑎𝑖+1ai=ai+1. We are allowed to do the following operation:

  • Select two integers 𝑖i and 𝑥x such that 1𝑖𝑛11≤i≤n−1 and 1𝑥1091≤x≤109. Then, set 𝑎𝑖ai and 𝑎𝑖+1ai+1 to be equal to 𝑥x.

Find the minimum number of operations needed such that the equality of the array is less than or equal to 11.

Input

Each test contains multiple test cases. The first line contains a single integer 𝑡t (1𝑡1041≤t≤104) — the number of test cases. The description of the test cases follows.

The first line of each test case contains an integer 𝑛n (2𝑛21052≤n≤2⋅105) — the length of array 𝑎a.

The second line of each test case contains 𝑛n integers 𝑎1,𝑎2,,𝑎𝑛a1,a2,…,an (1𝑎𝑖1091≤ai≤109) — elements of the array.

It is guaranteed that the sum of 𝑛n over all test cases does not exceed 21052⋅105

Output

For each test case, print the minimum number of operations needed.

 

배열에서 arr[i] == arr[i + 1] 이 되는 경우가 최대 1회가 되도록 하는 문제입니다.

임의로 x를 골라서 arr[x]와 arr[x + 1]을 내가 원하는 값으로 바꿔주는 작업을 해줄 수 있습니다.

위의 작업을 하는 최소의 경우를 찾으면 됩니다.

 

예를 들어

1 1 2 5 4 1 1

이런 배열을 받은 경우 결국 양 끝의 2개가 있는 지점에서부터 가운데로 좁혀와서 중복되는 숫자를 없애줘야 최솟값이 됩니다.

1 1 2 5 7 7 1 -> 1 9 9 5 7 7 1 -> 1 9 8 8 7 7 1 -> 1 9 8 3 3 7 1

양 끝에서 연속되는게 언제 등장하는지 구해서 그 사이만큼 저렇게 변화시키는 값을 구해주면 됩니다.

#include <stdio.h>
int main() {
    int t;
    int arr[200001] = {};
    scanf("%d", &t);
    for(int i = 0; i <t; i++) {
        int n, temp = 0;
        scanf("%d", &n);
        for(int j = 0; j < n; j++) {
            scanf("%d", &arr[j]);
        }
        int count = 1, cc = 0;
        int startpoint = 0, end = 0;
        for(int j = 1; j < n; j++) {
            if(arr[j] == arr[j - 1]) {
                startpoint = j;
                break;
            }
        }
        for(int j = n - 1; j > 0; j--) {
            if(arr[j] == arr[j - 1]) {
                end = j;
                break;
            }
        }
        if(end - startpoint < 1) cc = 0;
        else if(end - startpoint <= 2) cc= 1;
        else cc = end - startpoint -1;
        printf("%d\n", cc);
    }
}

 

안녕하세요.
백준보다 코드포스가 더 유익할 것 같아 코드포스를 하려고 합니다.
그런 김에 요즘 하루에 두어개 씩 문제를 푸는데 이 문제에 가장 시간을 오래 써서 가져와봤습니다.
근데 저 말고 다른 사람들도 많이 헤멘건지 carrot을 통해 확인해보니 풀기만 하면 그린 티어인 문제였습니다.

크롬의 확장프로그램 carrot을 통해 확인한 건데, 패널티를 엄청 먹고도 풀기만 하면 1330점 대의 mmr이 책정되는 것을 볼 수 있습니다.
코드포스도 mmr이 맞나요? 아무튼
문제는 이렇습니다.

캐릭터를 생성하는데 스텟을 찍을 겁니다.
스텟을 전부 찍었을 때 힘(srt)이 지능(int)을 초과하는 경우의 수를 출력해주면 됩니다.
ex) 힘 6 지능 4 스텟 3일 경우

지능
9 4
8 5
7 6

로 3가지 입니다.

문제는 아주 짧고 간단하죠?

입력으로는 test case 의 횟수인 t가 먼저 입력되고,
t회만큼 힘, 지능, 추가 스텟이 입력됩니다.

저는 예외사항에 대해 경우를 나눠서 계산해줬는데요.
1. 힘에 스텟을 전부 찍었는데 여전히 힘이 지능보다 낮을 경우
ex) 힘 5 지능 10 스텟 5 이면 힘에 전부 찍어도 10/ 10으로 힘이 높지 않습니다.

2. 스텟을 추가로 찍을 수 없지만 이미 힘이 지능보다 클 경우 정도입니다.
ex) 힘 5 지능 4 스텟 0이면 이미 힘이 높습니다. -> 경우의 수는 1

기본적으로 이 글을 보고 계시고 제 풀이 방법이 마음에 들어서 읽고 계신다면 위의 내용은 이미 다 알고 계실 것이고 저랑 같은 부분에서 막히지 않을까 생각이 드는데요, 제가 막힌 부분에 대해서 설명드릴게요.

힘이 지능+스텟 보다 높을 때의 계산이 문제였습니다.
ex) 힘 5 지능 0 스텟 3

지능
8 0
7 1
6 2
5 3

지능+ 스텟 < 힘
일 경우 경우의 수는 스텟 + 1이 됨이 당연합니다. 이 부분에 신경 써주시면 풀 수 있을 겁니다.
저는 뭐에 홀렸는지 위와 같은 상황에서 스텟 * 2를 출력해주고 있어서 계속 틀렸습니다.
중간에 뭘 틀렸는지 모르겠어서 계속 보고 한국어로 검색도 해봤는데 나오는게 없어서 제가 적었습니다.

처음에 이 실수만 안 하고 빠르게 제출했으면 민트 커트라인인 거로 보았을 때 확실히 사람들이 실수를 많이 한 문제인 것으로 판단되네요.
수고하세요

#include <stdio.h>
int main() {
    int s,i,e;
    int n;
    scanf("%d", &n);
    for(int p = 0; p < n; p++) {
        int count = 0; //경우의 수를 담을 변수입니다.
        scanf("%d %d %d", &s, &i, &e);
        if(s + e <= i) count = 0;//힘에 스텟을 전부 찍었는데도 지능보다 낮으면 경우의 수는 0
        else if(s + e > i) {
            count += (s + e - i) / 2;
            if((s + e - i) % 2 == 1) count++;
            if(s > e + i) {
                count += e;
            }
        }
        if(e == 0 && count > 0) count = 1;
        if(e == 0 && s > i) count = 1; //추가 스텟이 없는데 이미 힘이 지능보다 클 경우 1
        else if(count > e * 2) count = e + 1; //이 부분을 제대로 처리 못했습니다.
        printf("%d\n", count);
    }
}

+ Recent posts