알고리즘/백준 문제풀이

[삼성SW역량][Python/BOJ] 백준 16236 마법사 상어와 파이어볼(구현)

개발자 덕구🐾 2022. 7. 22. 10:59
728x90

 

 

 

 

처음 문제를 풀때 for문으로만 주구장창 풀었다.

코드는 더러워지고 길어졌다. 

게다가 답도 제대로 나오지않았다. 

 

처음부터 mp에 넣고 결과를 구했기 때문이다. 

fireball이라는 리스트를 만들어 이용하면 더 간편하고 깔끔하게 풀이할 수 있다.

 

 

 

 

문제에는 아래와 같은 문구가 있다. 

1번 행과열이 n번 행과열과 붙어있다는 의미이므로 nr과 nc를 구해도 다시 안으로 돌아도록 %n을 해주면된다. 

nr = (cr+(cs*dx[cd])) % n
nc = (cc+(cs*dy[cd])) % n 

 

 

 

dx와 dy는 문제의 0,1,2,....7 방향대로 맞추어서 설정해준다. 

 

 


 

 

문제 풀이 : 

 

 

1. fireball 리스트에 입력받는다.

2. k번 반복한다.

    2-1. fireball들을 리스트에서 꺼내서 이동시킨후 mp에 넣는다.

    2-2. 한 자리에 fireball이 2개 이상이라면 4개로 쪼개어 다시 fireball리스트에 넣어준다.

    2-3. 1개뿐이라면 fireball 리스트에 넣어준다. 

3. fireball 리스트의 m값을 모두 더한 값을 출력한다. 

 

 

 

 

코드 : 

dx = [-1,-1,0,1,1,1,0,-1]
dy = [0,1,1,1,0,-1,-1,-1]

    
if __name__=="__main__" :
    n,m,k = map(int,input().split())
    mp= [[[]for i in range(n)] for _ in range(n)]
    fireballs = []
    
    # fireball 입력받기 
    for i in range(m) :
        input_val = list(map(int,input().split()))
        fireballs.append(input_val )
    
    
    for _ in range(k) :
        
        # 파이어볼 자신의 방향으로 속력만큼 이동 
        while fireballs : 
            cr,cc,cm,cs,cd = fireballs.pop(0)
            nr = (cr+(cs*dx[cd])) % n
            nc = (cc+(cs*dy[cd])) % n
            mp[nr][nc].append([cm,cs,cd])

        # 2개 이상의 파이어볼이 같이 있다면 ?
        for i in range(n) :
            for j in range(n) :
                
                # 2개 이상인 경우 
                if len(mp[i][j])>=2 :
                    sum_m,sum_s,cnt_odd, cnt_even,cnt = 0,0,0,0,len(mp[i][j])
                    while mp[i][j] :
                        val = mp[i][j].pop(0)
                        sum_m += val[0]
                        sum_s += val[1]
                        if val[2] %2 : # direction이 홀수 
                            cnt_odd += 1
                        else :
                            cnt_even +=1  # direction이 짝수 
                    if cnt_even == cnt or cnt_odd == cnt : # 모두 짝수거나 홀수라면 
                        nd = [0,2,4,6]
                    else :
                        nd = [1,3,5,7]
                    if sum_m // 5 : # 5로 나우었을 때 값이 있다면 
                        for d in nd :
                            fireballs.append([i,j,sum_m//5,sum_s//cnt,d])
                # 1개일 경우
                if len(mp[i][j])==1 :
                    fireballs.append([i,j] + mp[i][j].pop())
                    
    # 남아있는 파이어볼 질량의 합
    print(sum([f[2] for f in fireballs]))

 

 

 

참고 블로그 : 

https://jennnn.tistory.com/77

 

[백준] 20056. 마법사 상어와 파이어볼 / python 파이썬

🚩 시뮬레이션, 구현 * 삼성 SW 역량 테스트 기출 문제 thinking "격자의 행과 열은 1번부터 N번까지 번호가 매겨져 있고, 1번 행은 N번과 연결되어 있고, 1번 열은 N번 열과 연결되어 있다." 난 이게

jennnn.tistory.com

 

반응형