[24.02.21] CF Round 922 div. 2 upsolve +

2024. 2. 21. 13:35·PS 기록/내실 쌓기

A번은 문제를 잘 읽어봐야 한다. 굳이 N * M 넓이의 wall을 세로 벽돌까지 써서 채워야 할 필요가 없고 가로 벽돌만 채우면 된다.

import sys
input = sys.stdin.readline
 
T = int(input())
for _ in range(T):
    N, M = map(int, input().split())
 
    #가로(M) == K 일 때, 벽돌 N개
    tmp = M//2*N
    print(max(N, tmp))

 

 

B번은 inversion을 최소화하는 문제이다. (i, j) 인덱스 순서쌍이 있고, i < j 인데 arr[i] > arr[j] 인 경우 inversion 상태라고 정의한다. 이 상태를 최소화 시키기 위해서 우리는 A arr, B arr에서 동시에 스왑을 해줘야한다. (i, j) -> (j, i) 이렇게 스왑을 해야하는데, 문제는 두 개의 리스트를 모두 고려해야 하기 때문에 복잡해진다.

나는 처음에 하나씩 그려보면서 어떻게 스왑해야하는지 고민했다. 일단 N/2 을 기준으로 a[i], b[i] 값이 앞에 있으면서 N/2보다 큰 것을, (N/2 기준) 뒤에 있으면서 값이 N/2 보다 작은 a[j]와 b[j] 를 골라 서로 스왑하는건가? 싶어서 시도해봤다.

그러나 친절하게도 예제 1번을 보면

1 2 3 4 5

5 4 3 2 1 

이런 경우에서 절대 움직일수가 없다. 흠... 절대 움직일수가 없다고..?

1번에 대한 답 inversion을 계산해봤더니 처음 상태나 답이나 둘다 10으로 같았다... 한 쪽이 일단 정렬되면 다른 쪽에서만 나오는 inversion 의 합이 무조건 최소가 되는 건가 싶어서 정렬로 때려 맞추기를 해도 되나? 의심을 했다.

결국 증명을 위해 에디토리얼을 봤는데 정렬하는게 맞았고, 한 쪽을 정렬하면 다른 리스트의 inversion의 합이 최소가 될 수 밖에 없는 이유에 대해 이해할 수 있었다.

 

원문은 영어로 되어있는데, 간단하게 한글로 정리해보자.

우리는 i, j 를 서로 스왑해줄건데, 스왑하기 전에 a[i], a[j] 라는 임의의 한 순서쌍에서 inversion이 있을 수도 있고 없을 수도 있다. (0 or 1) 여기에다가 우리는 b[i], b[j] 도 같이 스왑해야하는데, 기존의 이 순서쌍도 inversion을 0 or 1 개 가지고 있을 것이다.

그렇다면 스왑을 진행했을 때 어떻게 될까? 각각 (ai-aj 의 inversion 개수, bi-bj 의 inversion 개수) 라고 하자.

(0, 0) -> (1,1)  총 inverison 개수 0개 to 2개

(1, 0) -> (0, 1)   총 inverison 개수 1개 to 1개

(0, 1) -> (1, 0)  총 inverison 개수 1개 to 1개

(1, 1) -> (0, 0)  총 inverison 개수 2개 to 0개

 

여기서 어떤 i, j를 잡아도 A list와 B list 에서 inversion의 개수가 1이라면 계속 inversion의 수가 더 늘어나지 않고 같다. 이 조건을 가장 쉽게 맞춰줄 수 있는 방법이 A든 B든 둘 중 하나를 기준으로 정렬을 해주는 거다.

그러면 한 쪽 리스트는 이미 정렬되어 있기 때문에 어떤 i, j를 잡아도 inversion이 안나온다. 무조건 반대 리스트에서만 inversion이 나올 수 있고, 각 쌍의 인덱스 i와 j에는 최대 1개의 inversion만 있으므로 두 인덱스의 모든 쌍(a, b)이 교환될 때의 inversion 개수 보다 많아질 수 없다.

 + 이걸 스스로 증명까지 해냈어야 했는데 증명하지 못한게 아쉽다. 그냥 임의의 일반항 ai, aj / bi, bj 에 대해서 서로 순서를 바꾸면 어떻게 될지 차근차근 접근했으면 증명까지 도달할 수 있었을텐데... 아쉬운 마음이 들었다. 

i < j 로 순서가 정해져 있었기 때문에 서로 exchange 했을 때 무슨 일이 일어날지만 보면 된다. 이미 캠프에서 그리디 하면서 배운 내용인데 아직 실전에서 적용이 덜 됐구나 싶었다.

코드는 그냥 정렬하고 출력하면 된다.

import sys
input = sys.stdin.readline

T = int(input())
for _ in range(T):
    N = int(input())
    ali = list(map(int, input().split()))
    bli = list(map(int, input().split()))
    res = [[0, 0] for _ in range(N)]

    for i in range(N):
        res[i][0] = ali[i]
        res[i][1] = bli[i]

    res.sort()

    for i in range(N):
        print(res[i][0], end = ' ')
    print()
    for i in range(N):
        print(res[i][1], end = ' ')
    print()

 

 

C번은 내게 도전하는 느낌을 줬다. 비트에 대해 배워도 뭔가 직접 코드로 비트 연산을 해보려고 하면 어렵다. 아마 비트 문제를 거의 안풀어봐서 그런 것 같다. 비트마스킹 문제나 dp_bitfield 이런 것도 많이 해봐야한다.

 


 

일단 오늘은 신촌 도로망 관리와 쿼리 문제를 꼭 풀 생각이다. https://www.acmicpc.net/problem/31427

 

31427번: 신촌 도로망 관리와 쿼리

2025년, 신촌의 다섯 대학교인 서강대, 숙명여대, 연세대, 이화여대, 홍익대는 신촌에서 원활하게 통행하기 위한 도로망을 구축하고 관리하기로 결정하였다. 신촌은 $N$개의 정점으로 이루어져 있

www.acmicpc.net

 

그동안 이 문제에 대해서 고민을 너무 많이했다. 씻을 때 5! 를 어떤 방법으로 처리할지 생각하면서 씻었는데 이 방법이 되는지 안되는지를 빨리 코드로 짜봐야 답답함이 풀릴 것 같다.

저작자표시 비영리 변경금지

'PS 기록 > 내실 쌓기' 카테고리의 다른 글

[24.02.20] CF Round 927 div. 3 virtual + Gold 한 문제 풀기  (0) 2024.02.20
회고  (0) 2024.02.19
'PS 기록/내실 쌓기' 카테고리의 다른 글
  • [24.02.20] CF Round 927 div. 3 virtual + Gold 한 문제 풀기
  • 회고
pearl.k
pearl.k
이화여대 공대, PS, 개발
  • pearl.k
    Pearl
    pearl.k
  • 전체
    오늘
    어제
    • 분류 전체보기 (53)
      • Java Spring (10)
      • Android (1)
      • Kotlin (7)
      • Coroutines (2)
      • PS 기록 (20)
        • CP (6)
        • Algorithm (6)
        • 내실 쌓기 (3)
      • CS (0)
      • IT - 취업 DB (5)
      • SSAFY (2)
        • Algorithm (1)
      • Daily (3)
      • Books (2)
      • 기타 부트캠프 기록 (0)
        • 네이버 부스트캠프 (0)
        • 우아한테크코스 (0)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

    • Github
  • 공지사항

  • 인기 글

  • 태그

    앳코더후기
    java
    백준 2423
    싸피 면접 후기
    다익스트라
    백준 13334
    solved.ac
    싸피 12기
    sw마에스트로 코테
    액티비티컴포넌트
    앳코더309
    첫앳코더
    싸피 서울캠
    채용의나라
    Grand Arena Party div2
    웹모바일과정
    코딩테스트
    백준
    http stream
    자바@
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
pearl.k
[24.02.21] CF Round 922 div. 2 upsolve +
상단으로

티스토리툴바