Codeforces Round #804 (Div. 2) ABC

3Juhwan·2022년 7월 6일
0

Codeforces

목록 보기
19/24
post-thumbnail

[12번째 Contest]

방학 안에 100개의 콘테스트에 참가할 수 있을까..?

대회 준비로 코포에 집중을 못하고 있다. 이전에 1일 1버추얼 돌리다가 그린까지 떨어지는 대참사를 겪었기에 버추얼을 함부로 못하겠다..

오늘 코포는 AB가 굉장히 쉬웠는데, C가 C답지 않게 어려웠다.

A. The Third Three Number Problem

nn이 주어진다. 우리는 다음 수식을 만족하는 a,b,ca, b, c를 결정해야 한다.

(ab)+(bc)+(ca)=n(a \oplus b)+(b \oplus c)+(c \oplus a)=n

풀이

nn이 홀수면, 조건을 만족하는 정답은 없다. return1return -1
이건 a,b,ca, b, c에 홀수, 짝수를 잘 조합해보면 바로 알 수 있다.

a,ba, b00으로 고정시키고 풀면 간단하다. 전형적인 코포스타일 문제.
a=0,b=0a=0, b=0으로 두면, 위 식은 간단하게 정리된다. 2c=n2*c=n 이고, c=n/2c = n/2이다

코드

def solve():
    n = int(input())
    if n%2:
        print(-1)
    else:
        print(0, 0, n//2)

for __ in range(int(input())):
    solve()

B. Almost Ternary Matrix

n,mn, m이 주어진다. nmn*m짜리 그리드를 0011로 채워야 한다. 문제는, 이웃한 숫자들 중에 다른 숫자가 딱 22개 존재하게 채워야 한다. 예를 들면, 00으로 채워진 칸은 이웃한 칸에 11이 딱 22개 존재해야 한다.

풀이

구성적 느낌의 문제다. 다음 패턴을 확장, 반복해서 출력하면 된다.
직접 그림을 그려가며 패턴을 찾아야 한다.

1 0 0 1
0 1 1 0 
0 1 1 0
1 0 0 1

코드

dp = [[1, 0, 0, 1]*50, [0, 1, 1, 0]*50, [0, 1, 1, 0]*50, [1, 0, 0, 1]*50]*50
 
def solve():
    a, b = map(int, input().split())
    for d in dp[:a]:
        print(*d[:b])  

    
for __ in range(int(input())):
    solve()

C. The Third Problem

길이가 nnpermutationpermutation aa가 주어진다. 우리는 모든 구간에서 aasimilarsimilarpermutationpermutation bb를 만들어야 한다. similarsimilar의 조건은 다음과 같다.

모든 구간 [l,r][l, r]에 대해서 MEX([al,al+1,...,ar])=MEX([bl,bl+1,...,br])MEX([a_l, a_{l+1}, ..., a_{r}]) = MEX([b_l, b_{l+1}, ..., b_{r}])를 만족하면 similarsimilar하다.

풀이

aa에서 ii의 위치를 p[i]p[i]라고 가정하자. bb에서 00의 위치를 잘 생각해보자. bb에서 00의 위치는 반드시 p[0]p[0]이다. MEX([ap[0]])=1MEX([a_{p[0]}])=1 이기 때문이다. bb에서 11의 위치도 고민해보자. 11 역시 p[1]p[1]에 위치한다.

구간 [l,r][l, r]을 정의해보자. l=p[0],r=p[1]   (p[0]<p[1])l=p[0], r=p[1] \;\ (p[0]<p[1])이라고 가정하자. 이때, aa에서 22의 위치를 생각해보자.

l<p[2]<rl < p[2] < r 이라면, bb에서 22는 구간 [l,r][l,r] 안에 존재해야 한다. 이거에 대한 정당성은 에디토리얼에 자세히 적혀 있다. 이 경우에, ans  =(rl+1i)ans \; *= (r-l+1-i) 해준다. (rl+1i)(r-l+1-i)은 구간 [l,r][l,r]에서 22가 위치할 수 있는 경우의 수다.

p[2]p[2]가 구간 밖에 존재한다면, 구간 [l,r][l,r]p[2]p[2]를 포함하는 구간으로 적절히 갱신해준다.

코드

MOD = 1_000_000_007

def solve():
    n = int(input())
    a = list(map(int, input().split()))
    ans = 1

    p = [0]*n
    for i in range(n):
        p[a[i]] = i
        
    l, r = p[0], p[0]

    for i in range(1, n):
        idx = p[i]
        if l < idx < r:
            ans *= (r-l+1-i)
            ans %= MOD
        l = min(l, idx)
        r = max(r, idx)
        
    print(ans)
    
for __ in range(int(input())):
    solve()
profile
Codeforces와 USACO 풀이를 기록합니다. 이전 글도 계속 업데이트 됩니다.

0개의 댓글