대회 정보: https://www.acmicpc.net/contest/view/303
문제 목록: https://www.acmicpc.net/category/detail/1889

출제 및 검수 : bryan, chogahui05, exqt, jh05013, jwvg0425, pinch3773, wookje

문제 A B C D E
출제자 jwvg0425 wookje wookje wookje wookje

예선 출제에 수고해주신,
그리고 본선도 수고해주실 출제진 여러분들께 감사의 말씀 올립니다.

A. 고장난 시계

풀이

15885 : 고장난 시계

흘러간 시간이 t시간일 때,

정상 시계는 t % 12를 가리키고

상대속도 x가 곱해진 시계는 t * x % 12를 가르킨다.

이를 이용해 수식을 유도하여 답을 구할 수 있다.

abs(a/b-1) * 2에서 정수만 취한 값이 답이다.

코드

// C/C++
#include <cstdio>
int abs(int a) { return a < 0 ? -a : a; }
int main() {
    int a, b;
    scanf("%d %d", &a, &b);
    printf("%d", abs(a - b) * 2 / b);
    return 0;
}
# python3
a, b = map(int,input().split())
print(abs(a-b)*2//b)

B. 내 선물을 받아줘 2

풀이

15886 : 내 선물을 받아줘 2

이동을 시작하는 위치에 상관 없이,

구사과는 항상 인접한 두 칸을 반복해서 돌아다니게 된다.

이러한 인접한 두 칸은 여러개가 있을 수 있다.

그리고 그러한 인접한 두 칸들은 항상 “EW”임을 알 수 있다.

E에 의해 오른쪽으로 가고, W를 만나 왼쪽으로 가는 이동을 반복하기 때문이다.

따라서 주어진 문자열에서 EW의 개수를 찾아서 출력하면 된다.

코드

// C/C++
#include <cstdio>
int n;
char str[1005];
int main() {
    scanf("%d %s", &n, str);
    int ans = 0;
    for (int i = 0; i < n-1; i++) {
        if (str[i] == 'E' && str[i+1] == 'W') {
            ans++, i++;
        }
    }
    printf("%d", ans);
    return 0;
}
# python3
n=int(input())
print(input().count("EW"))

C. 욱제는 결벽증이야!!

풀이

15887 : 욱제는 결벽증이야!!

어떤 L < R인 [L, R]을 reverse 할 수 있다면,

[i, i+1]을 reverse 할 수 있고 이는 swap 연산과 동치이다.

버블소트 등을 이용하는 등 여러가지 풀이가 존재할 수 있다.

코드

// C
#include <stdio.h>

int n, cnt;
int a[1001], x[1000001], y[1000001];

void swap(int *a, int *b) {
	int tmp = *a;
	*a = *b;
	*b = tmp;
}

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &a[i]);
    }
    for (int i = 0; i < n-1; i++) {
        for (int j = 0; j < n-i-1; j++) {
            if (a[j] > a[j+1]) {
                swap(&a[j], &a[j+1]);
                x[cnt] = j;
                y[cnt] = j+1;
                cnt++;
            }
        }
    }
    printf("%d\n", cnt);
    for (int i = 0; i < cnt; i++) {
        printf("%d %d\n", x[i]+1, y[i]+1);
    }
    return 0;
}
// C++
#include <cstdio>
#include <algorithm>
#include <vector>
using namespace std;

vector<pair<int, int> > v;

int n;
int a[1001], b[1001];

int main() {
    scanf("%d", &n);
    for (int i=1;i<=n;i++) {
        scanf("%d",a+i);
        b[a[i]] = i;
    }

    for (int i=1; i<=n; i++) {
        int x = i, y = b[i];
        if (x > y) swap(x, y);
        if (x != y) reverse(a+x, a+y+1), v.push_back({ x,y });
        for (int j = x; j <= y; j++) b[a[j]] = j;
    }

    printf("%d\n", v.size());
    for (auto it : v) {
        printf("%d %d\n", it.first, it.second);
    }

    return 0;
}
# python3
n = int(input())
arr = list(map(int,input().split()))
ans = []
for i in range(n):
    j = arr.index(i+1)
    if i == j: continue
    ans.append((i+1, j+1))
    arr[i:j+1] = reversed(arr[i:j+1])
print(len(ans))
for LR in ans: print(*LR)

D. 정답은 이수근이야!!

풀이

15888 : 정답은 이수근이야!!

이차방적식의 계수의 절댓값이 100을 넘지 않고, 항상 0이 아니다.

이를 통해 방정식의 해의 절댓값은 100을 넘지 않음을 알아낼 수 있다.

이를 통해 -100에서 100까지 모든 값을 방정식에 대입해볼 수 있다.

또 다른 풀이로는, 판별식과 근의 공식을 이용하여 잘 코딩하는 방법이 있다.

A, B, C의 범위가 작아 어지간하면 실수 오차는 발생하지 않는다.

물론 실수형을 사용하지 않고 잘 커팅하면 실수형을 쓰지 않고 후자의 방법으로 코딩할 수 있다.

코드

// C/C++
#include <cstdio>

const int p[6] = { 2,4,8,16,32,64 };

int main() {
    int a, b, c;
    
    scanf("%d %d %d", &a, &b, &c);

    int r_cnt = 0, p_cnt = 0;
    for (int x = -100; x <= 100; x++) {
        if (a*x*x + b*x + c == 0) {
            r_cnt++;
            for (int i = 0; i < 6; i++) {
                if (x == p[i]) p_cnt++;
            }
        }
    }

    if (r_cnt != 2) printf("둘다틀렸근");
    else if (p_cnt == 2) printf("이수근");
    else printf("정수근");

    return 0;
}
# python3
a, b, c = map(int,input().split())
pows = [2, 4, 8, 16, 32, 64]
root = 0
proot = 0
for x in range(-100, 101):
    if a*x*x + b*x + c == 0:
        root+= 1
        if x in pows: proot+=1
if root != 2: print("둘다틀렸근")
else: print("이수근" if proot == 2 else "정수근")

E. 호 안에 수류탄이야!!

풀이

15889 : 호 안에 수류탄이야!!

욱제(1번째)부터 시작하여 i번째 전우를 보고 있다고 하자.

각 전우들의 위치를 pos[i]라고 하자.

i번째까지의 모든 전우들이 각각의 위치에서 던질 수 있는 최대 사거리는 pos[i] + len[i]이다.

첫 번째 전우(욱제)부터 검사하면서 가장 긴 사거리를 갱신해 나가며 해결할 수 있다.

코드

// C/C++
#include <cstdio>

int n, pos[30003];

int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i++) {
        scanf("%d", &pos[i]);
    }
    int len = 0, max_len = 0;
    for (int i = 1; i < n; i++) {
        scanf("%d", &len);
        if (max_len < pos[i-1] + len) {
            max_len = pos[i-1] + len;
        }
        if (max_len < pos[i]) {
            printf("엄마 나 전역 늦어질 것 같아");
            return 0;
        }
    }

    printf("권병장님, 중대장님이 찾으십니다");

    return 0;
}

아무말

백준, 백준 온라인 저지, BOJ, Baekjoon Online Judge, wookje, 욱제, 풀이, 선린, 선린인터넷고등학교, sunrin, 문제 풀이, 제2회 천하제일 코딩대회, 준오, 임준오, junoim, 이수근, 군대, koosaga, 구사과, junoim, 임준오, 준오

wookje.kwon's profile image

wookje.kwon

2018-07-13 22:07

Read more posts by this author