TIL

[멋쟁이사자처럼 부트캠프 TIL회고] 53일차 : 일요일은 쉬는날

Cadi 2025. 1. 13. 10:13

코딩테스트 : 겹치는 선분의 길

선분 3개가 평행하게 놓여 있습니다. 세 선분의 시작과 끝 좌표가 [[start, end], [start, end], [start, end]] 형태로 들어있는 2차원 배열 lines가 매개변수로 주어질 때, 두 개 이상의 선분이 겹치는 부분의 길이를 return 하도록 solution 함수를 완성해보세요.

lines가 [[0, 2], [-3, -1], [-2, 1]]일 때 그림으로 나타내면 다음과 같습니다.

선분이 두 개 이상 겹친 곳은 [-2, -1], [0, 1]로 길이 2만큼 겹쳐있습니다.

using System;
using System.Collections.Generic;

public class Solution {
    public int solution(int[,] lines) 
    {
        int answer = 0;
        Dictionary<int, int> count = new Dictionary<int, int>();

        for (int i = -100; i < 100; i++)
        {
            count.Add(i, 0);
        }

        for (int j = 0; j < lines.GetLength(0); j++)
        {
            for (int i = lines[j, 0]; i < lines[j, 1]; i++)
            {
                if (count.ContainsKey(i))
                {
                    count[i]++;
                }
            }
        }

        for (int i = -100; i < 100; i++)
        {
            if (count[i] > 1)
            {
                answer++;
            }
        }
        
        return answer;
    }
}

 

왜....인진 모르겠으나 한 번에 풀렸다.

당연히 오류가 날 것으로 예상하고 아무 생각 없이 돌렸는데 통과해서 당황했다.

처음에 Dictionary 써 보고 싶어서 쭉 쓰다가 아 그냥 배열 쓸 걸 하고 후회했지만 일단은 OK...

 

 

다른 사람의 흥미로운 풀이

 

의외로 다들 어렵게 푸신 것 같아 내가 운이 좋았던 것 같다. 한 번에 풀이가 생각나서 기분이 좋았다.

 

 

 

코딩테스트 : 유한소수 판별하기

소수점 아래 숫자가 계속되지 않고 유한개인 소수를 유한소수라고 합니다. 분수를 소수로 고칠 때 유한소수로 나타낼 수 있는 분수인지 판별하려고 합니다. 유한소수가 되기 위한 분수의 조건은 다음과 같습니다.

기약분수로 나타내었을 때, 분모의 소인수가 2와 5만 존재해야 합니다.
두 정수 a와 b가 매개변수로 주어질 때, a/b가 유한소수이면 1을, 무한소수라면 2를 return하도록 solution 함수를 완성해주세요

using System;

public class Solution {
    public int solution(int a, int b) 
    {
        int answer = 2;
        
        int largeNumber = (int)MathF.Max(a, b);

        if (b > 2)
        {
            for (int i = 2; i <= largeNumber; i++)
            {
                if (a % i == 0 && b % i == 0)
                {
                    a = a / i;
                    b = b / i;
                    i--;
                }
            }
        }
        while (b > 1)
        {
            if (b % 2 == 0)
            {
                b = b / 2;
            }
            else if (b % 5 == 0)
            {
                b = b / 5;
            }
        }
        if (b == 1)
        {
            answer = 1;
        }
        else
        {
            answer = 2;
        }
        return answer;
    }
}

 

밑에 힌트를 안보고 풀다가 시간제한에 걸렸다.

 

유한소수는 판별하지만, 유한소수가 아닌 것에 걸렸을 때는 루프에 걸린 것을 보니

while문의 활용이 잘못되었다. 나눠지면 > 유한소수 나눠지지 않으면 > 반복

 

나는 약분을 할 때에 작은 숫자부터 차례대로 했는데, 그냥 최대 공약수를 한 번만 나눠주면 되는 문제였다. 

 

using System;

public class Solution {
    public int solution(int a, int b) 
    {
        int answer = 2;
        
        //굳이 더 큰 수까지 나눗셈을 해 줄 필요 없음
        int largeNumber = (int)MathF.Max(a, b);
        // 어쩌피 작은 수 이상으로는 양쪽 수를 나누지 못함
        int smallerNumber = (int)MathF.Min(a, b);

        if (b > 2)
        {
            for (int i = smallerNumber; i >= 2; i--)
            {
                if (a % i == 0 && b % i == 0)
                {
                    a = a / i;
                    b = b / i;
                    break;
                }
            }
        }
      
        while (b % 2 == 0)
        {
            b = b / 2;
        }
        while (b % 5 == 0)
        {
            b = b / 5;
        }
        //나눴을 때 1 이 나오면 유한소수
        if (b == 1)
        {
            answer = 1;
        }
        //다른 숫자가 나누면 무한 소수
        else
        {
            answer = 2;
        }
        return answer;
    }
}

다른 사람의 흥미로운 풀이

 

나는 양쪽 숫자를 나눠줄 생각만 했었다.

그런데 그냥 B만 계속 2와 5로 나눌 수 있을때까지 나눠버리고,  나눠진 B로 분모인 A를 나눴을 때 나머지가 있으면

(나눠지지 않았으면) 무한소수이고, 나눠진다면 유한소수가 되어버린다. 

결국 목표는  '분모에서 2와 5를 제외한 숫자를 모두 없에는 것'이기 때문이다.