[백준] 10810번 공넣기

권태형·2024년 1월 17일

알고리즘

목록 보기
32/33

문제의 글이 많다. 문제와 문제아래의 입력, 출력을 보고 정리해보자

  1. 바구니의 개수
    바구니가 N개 있는데 각각의 바구니는 1~N의 번호가 적혀있으며 겹치지 않는다. 입력값의 제한조건을 봤을때 바구니의 개수는 1~100개의 랜덤한 개수를 가진다.

  2. 공의 개수
    공 또한 바구니와 마찬가지로 1~N의 번호가 적혀있으며 공을 많이 가지고 있다고 했으니 중복이 가능하다.

  3. 바구니는 처음에는 비워져 있다.

  4. 각 바구니에는 공을 1개만 넣을 수 있다.
    바구니에 이미 다른공이 들어가 있다면 기존공을 빼고 새로운 공을 넣는다.

  5. 콘솔 입력 첫째 줄에 N (1 ≤ N ≤ 100)과 M (1 ≤ M ≤ 100)이 주어진다.

  6. 공을 넣은 방법은 세 정수 i j k로 이루어져 있으며, i번 바구니부터 j번 바구니까지에 k번 번호가 적혀져 있는 공을 넣는다.

  7. 세 정수 i j k 는 첫번째 입력에 주어지는 N과 일치한다.

  8. 1번 바구니부터 N번 바구니에 들어있는 공의 번호를 공백으로 구분해 출력한다. 공이 들어있지 않은 바구니는 0을 출력한다.

내가 생각했을때 정리 했을때 유념해야할 점은 위의 8가지가 되겠다.


나의 풀이

// 1<=N<=100, 1<=M<=100  주어지는 식은 첫줄에 N과M을 한 줄에 콘솔입력,
// 둘 째줄 부터 M번 콘솔의 입력 i j k 가 주어진다.
// i 번 바구니부터 j 번 바구니까지 k번 공을 각각 넣는다.
// 출력은 배열의 첫수부터 a[0]의 인수까지 한다.
int[] a = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
int[] result = new int[100];

for(int m = 0; m < a[1]; m++){
    int[] b = Array.ConvertAll(Console.ReadLine().Split(), int.Parse);
    for(int i = b[0]-1; i < b[1]; i++){
        result[i] = b[2];
    }
}
        
for(int c = 0; c < a[0]; c++){
    Console.Write($"{result[c]} " );
}

다행히 한방에 성공하였다. 비록 변수가 이것저것 a, b, c 나만 알아 볼 변수 이름을 사용한게 불편하지만, i나 j, k 등을 문제내에서 입력 변수 이름으로 사용하였기에 가독성은 포기할 수 밖에 없었다.

코드의 가독성을 생각하면, Array.ConvertAll(Console.ReadLine().Split()도 따로 함수로 빼서 사용할 수도 있으나, 두 번 밖에 안 나오는 부분에 코스트를 사용하는건 아깝다고 생각되었다.

문제가 길어서 파악하는 시간이 오래걸린 문제였다. 누군가는 보자마자 인지했을지 모르겠지만, 나의경우 인지하는 시간만 10~15분이 넘게 걸렸다.

기본적으로 빈 배열을 생성하면, 모든 요소는 0이 되기때문에 문제에서 제시한 공이 들어있지 않는 바구니는 0으로 표기한다 부분을 깔끔하게 빈배열 생성으로 제거할 수 있다.

기본 1차원 배열에 해당하는 문제로써 최대한 이전에 지나온 문제풀이법을 사용하다보니 for문이 3번 사용되고, 실질적으로는 O(n^2) + O(n)의 시간복잡도를 가지게 되지만, 입력값의 제한이 최대 100인 점을 생각하면 최대 1만번밖에 안되기 때문에 2중for문을 작성하여도 시간적인 부분에서 큰 부하가 생기지 않아서 위와 같이 작성하였다.


다른사람 풀이

var a=Console.ReadLine().Split().Select(int.Parse).ToArray();
var r=new int[a[0]];

for(int i=0;i<a[1];i++){
	var b = Console.ReadLine().Split().Select(int.Parse).ToArray();
	for(int j=b[0]-1;j<b[1];j++)r[j]=b[2];
}

foreach(var c in r)Console.Write(c+" ");

위 다른 사람의 코드를 보면서 내 생각의 짧았던 점은, 변수의 최대 입력값이 100이라는 전제로 빈배열을 생성할때 100개의 공간을 미리 할당 하였다면, 이 코드는 어짜피 출력해야할 위치가 첫줄의 첫 입력값이기 때문에 해당 값으로 크기를 정했다는 것이다.

나는 i,j,k가 N보다 작다는 것을 N과 같은 범위를 가진다고 생각했기 때문에 나의 풀이에선 생성하는 배열의 크기를 N의 최대크기 100을 설정한건데, 문제를 자세히 읽어보니 i,j,k는 첫줄에 임력된 N값보다 작기 때문에 위와같은 풀이가 나온다.

다른 부분은 문자열을 숫자배열로 바꾸는 점에서 다른 메소드를 사용했지, 크게 시간복잡도가 다르거나 하진 않은 부분이었던 것같다.

좀 더 문제를 자세히 읽어보고 각 변수의 관계과 범위를 잘 생각해보면 더 깔끔한 코드가 나오지 않을까 싶다.

profile
22년 12월 개발을 시작한 신입 개발자 ‘권태형’입니다. 포스팅 하나하나 내가 다시보기 위해 쓰는 것이지만, 다른 분들에게도 도움이 되었으면 좋겠습니다. 💯컬러폰트가 잘 안보이실 경우 🌙다크모드를 이용해주세요.😀 지적과 참견은 언제나 환영합니다. 많은 댓글 부탁드립니다.

0개의 댓글