본문 바로가기

문제 노트/정올

카드 바꾸기( BOJ 25401 )

문제 : https://www.acmicpc.net/problem/25401

 

25401번: 카드 바꾸기

$N$개의 카드가 놓여있다. 편의상 가장 왼쪽에 있는 카드를 $1$번 카드, 그 다음에 있는 카드를 $2$번 카드 $\dots$, 가장 오른쪽에 있는 카드가 $N$번 카드라고 하자. $N$개의 카드에는 각각 정수가 하

www.acmicpc.net

 

문제 파악하기

N개의 카드를 등차수열로 만드는 문제입니다. 공차는 음수, 0, 양수 모두 될 수 있으며, 주어진 N개의 숫자 중 일부분을 바꿔 등차수열로 만들었을 때, 바꾼 카드 수의 최솟값을 구해야 합니다. 등차 수열을 만드는 가장 간단한 방법은 모든 숫자를 하나의 숫자로 통일하는 것입니다. 하지만 이 방법은 비효율적이기에 조금 더 효율적인 방법이 필요하며, 이 때에는 2개의 숫자를 기준으로 활용할 수 있습니다.

 

문제 해결하기

입력되는 N개의 숫자는 최대 500개입니다. 따라서, 우리는 두 숫자를 기준으로 설정하는 중첩 반복문을 활용할 수 있습니다. 그리고 2개의 숫자를 기준으로 설정하면 다음은 간단합니다. 공차가 정수로 만들어질 수 있는지 확인한 다음, 만들 수 있다면 첫 항을 구한 다음, 현재 수열과 비교해서 다른 숫자의 개수를 세면 됩니다. 두 수를 사용해 만들 수 있는 모든 수열을 확인하고 그 중 최솟값을 구하면 우리가 원하는 결괏값을 얻게 됩니다.

 

소스코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <stdio.h>
#include <algorithm>
#define NMAX 505
using namespace std;
 
int N;
int inp[NMAX];
 
int d, val, tcnt, ret;
 
int main() {
    scanf("%d"&N);
    for(int i=1;i<=N;i++scanf("%d"&inp[i]);
    
    ret = N-1;
    for(int i=1;i<=N;i++) {
        for(int j=i+1;j<=N;j++) {
            // inp[i] + (j-i)*d = inp[j]
            if((inp[j]-inp[i])%(j-i) != 0continue;
            
            d = (inp[j]-inp[i])/(j-i);
            
            val = inp[i] - (i-1)*d;
            tcnt = 0;
            for(int k=1;k<=N;k++) {
                if(val != inp[k]) tcnt++;
                
                val += d;
            }
            
            ret = min( ret, tcnt );
        }
    }
    
    printf("%d", ret);
}
 
cs

후기

정올 초등학교 문제답게 어려운 개념이 필요하지 않았습니다. 정올의 맛을 느낄 수 있기에 정올을 소개할 때, 사용할 수 있는 간단한 문제라고 생각합니다. 문법을 마친 다음, 정올을 시작하는 사람에게 추천하고 싶은 문제입니다.

'문제 노트 > 정올' 카테고리의 다른 글

트리와 쿼리( BOJ 25402 )  (1) 2022.09.30
커다란 도시( BOJ 25380 )  (1) 2022.09.26
조약돌( BOJ 25378 )  (1) 2022.09.20
창고 다각형( BOJ 2304 )  (0) 2022.08.11
산만한 고양이( BOJ 14866 )  (0) 2022.08.06