주녘공부일지

[프로그래머스 C#] Lv.2 충돌위험 찾기 (PCCP 기출문제 3번) 본문

CodingTest/Programmers Lv.2

[프로그래머스 C#] Lv.2 충돌위험 찾기 (PCCP 기출문제 3번)

주녘 2024. 9. 23. 21:28

https://school.programmers.co.kr/learn/courses/30/lessons/340211

 

프로그래머스

코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

programmers.co.kr

1. 정답코드 및 핵심 아이디어, 유의사항

로봇을 이용한 자동 운송 시스템을 운영했을 때, 충돌 위험 상황 발생 횟수를 구하는 문제

- 충돌 위험 상황은 좌표마다 카운트 됨 ( 한 좌표에 2마리 이상이 있을 경우 1회 )

- 문제의 그림을 기준으로 x축보다 y축을 우선으로 이동 ( 무조건 y축 먼저 이동 )

- 모든 로봇의 이동 속도는 같으며, 로봇은 모든 경로를 이동할 때까지 멈추지 않음

 

풀이 순서 ( 이동 중인 로봇이 1대 이하가 될 때까지 반복 )

1. 실제 이동 가능 좌표들을 2차원 배열로 나타냄 ( index : 위치, value : 로봇의 수 )

2. 현재 로봇의 위치를 이동 위치에 따라 갱신 ( 현재 위치 삭제 -> 이동 -> 갱신된 위치 추가 )

3. 한번의 이동이 발생했을 때 충돌 판단 ( 배열을 순회하며 로봇이 2대 이상인 좌표를 탐색 )

 

코드 참조

using System;
using System.Collections.Generic;

public class Solution
{
    public class Pos
    {
        public int y, x;
        
        public Pos(int y, int x)
        {
            this.y = y;
            this.x = x;
        }
    }
    
    public class Robot
    {
        public Pos pos;
        public List<Pos> posList;
        
        public Robot(Pos pos)
        {
            this.pos = pos;
            posList = new List<Pos>();
        }
        
        public bool MovePos(ref int[,] intArrays)
        {
            if(posList[0].y == pos.y && posList[0].x == pos.x)
                posList.RemoveAt(0);
            
            // 기존 위치 삭제
            intArrays[pos.y, pos.x]--;
            
            if(posList.Count == 0)
                return false;
            
            // 위치 갱신 및 추가
            if(posList[0].y != pos.y)
            {
                if(posList[0].y > pos.y)
                    pos.y++;
                else
                    pos.y--;
            }
            else if(posList[0].x != pos.x)
            {
                if(posList[0].x > pos.x)
                    pos.x++;
                else
                    pos.x--;
            }
            
            intArrays[pos.y, pos.x]++;
            return true;
        }
    }
    
    public int solution(int[,] points, int[,] routes)
    {
        int answer = 0;
        int[,] intArrays = new int[101, 101]; // 이동 가능 좌표 배열
        
        // Robot List 세팅, 출발 위치 세팅
        List<Robot> list = new List<Robot>();
        for(int i = 0; i < routes.GetLength(0); i++)
        {
            int index = routes[i, 0] - 1;
            Pos pos = new Pos(points[index, 0], points[index, 1]);
            Robot robot = new Robot(pos);
            
            intArrays[pos.y, pos.x]++;
            
            for(int j = 1; j < routes.GetLength(1); j++)
            {
                index = routes[i, j] - 1;
                pos = new Pos(points[index, 0], points[index, 1]);
                robot.posList.Add(pos);
            }
            
            list.Add(robot);
        }
        
        foreach(int i in intArrays)
                if(i > 1)
                    answer++;
        
        while(list.Count > 1)
        {
            // 위치 갱신
            List<int> removeList = new List<int>();
            for(int i = list.Count - 1; i >= 0; i--)
            {
                bool b = list[i].MovePos(ref intArrays);
                
                if(b == false)
                    removeList.Add(i);
            }
            
            foreach(int i in removeList)
                list.RemoveAt(i);
            
            foreach(int i in intArrays)
                if(i > 1)
                    answer++;
        }
        
        return answer;
    }
}