2W.4D- 백준 15686

Dazz_heyDay ·2021년 7월 8일
1

Python) Algorithm_study

목록 보기
9/39

✏️문제15686 [치킨배달]

<문제>

크기가 N×N인 도시가 있다. 도시는 1×1크기의 칸으로 나누어져 있다. 도시의 각 칸은 빈 칸, 치킨집, 집 중 하나이다. 도시의 칸은 (r, c)와 같은 형태로 나타내고, r행 c열 또는 위에서부터 r번째 칸, 왼쪽에서부터 c번째 칸을 의미한다. r과 c는 1부터 시작한다.

이 도시에 사는 사람들은 치킨을 매우 좋아한다. 따라서, 사람들은 "치킨 거리"라는 말을 주로 사용한다. 치킨 거리는 집과 가장 가까운 치킨집 사이의 거리이다. 즉, 치킨 거리는 집을 기준으로 정해지며, 각각의 집은 치킨 거리를 가지고 있다. 도시의 치킨 거리는 모든 집의 치킨 거리의 합이다.

임의의 두 칸 (r1, c1)과 (r2, c2) 사이의 거리는 |r1-r2| + |c1-c2|로 구한다.

예를 들어, 아래와 같은 지도를 갖는 도시를 살펴보자.

0은 빈 칸, 1은 집, 2는 치킨집이다.

(2, 1)에 있는 집과 (1, 2)에 있는 치킨집과의 거리는 |2-1| + |1-2| = 2, (5, 5)에 있는 치킨집과의 거리는 |2-5| + |1-5| = 7이다. 따라서, (2, 1)에 있는 집의 치킨 거리는 2이다.

(5, 4)에 있는 집과 (1, 2)에 있는 치킨집과의 거리는 |5-1| + |4-2| = 6, (5, 5)에 있는 치킨집과의 거리는 |5-5| + |4-5| = 1이다. 따라서, (5, 4)에 있는 집의 치킨 거리는 1이다.

이 도시에 있는 치킨집은 모두 같은 프랜차이즈이다. 프렌차이즈 본사에서는 수익을 증가시키기 위해 일부 치킨집을 폐업시키려고 한다. 오랜 연구 끝에 이 도시에서 가장 수익을 많이 낼 수 있는 치킨집의 개수는 최대 M개라는 사실을 알아내었다.

도시에 있는 치킨집 중에서 최대 M개를 고르고, 나머지 치킨집은 모두 폐업시켜야 한다. 어떻게 고르면, 도시의 치킨 거리가 가장 작게 될지구하는 프로그램을 작성하시오.

입력조건
첫째 줄에 N(2 ≤ N ≤ 50)과 M(1 ≤ M ≤ 13)이 주어진다.
둘째 줄부터 N개의 줄에는 도시의 정보가 주어진다.
도시의 정보는 0, 1, 2로 이루어져 있고, 0은 빈 칸, 1은 집, 2는 치킨집을 의미한다. 집의 개수는 2N개를 넘지 않으며, 적어도 1개는 존재한다. 치킨집의 개수는 M보다 크거나 같고, 13보다 작거나 같다.
출력조건
첫째 줄에 폐업시키지 않을 치킨집을 최대 M개를 골랐을 때, 도시의 치킨 거리의 최솟값을 출력한다.

from itertools import combinations

n,m=map(int,input().split())
array=[list(map(int,input().split())) for _ in range(n)]

C=[] #치킨집
H=[] #집

for i in range(n):
    for j in range(n):
        if array[i][j]==1:
            H.append((i,j)) #집 위치
        elif array[i][j]==2:
            C.append((i,j)) #치킨집 위치

for chicken in combinations(C,m): #조합이용 #m개의 치킨집만 필요
    hap=0
    mini=float('inf') #양의 무한대
    for home in H:
        hap=hap+min([abs(home[0]-k[0])+ abs(home[1]-k[1]) for k in chicken]) #거리는 양수,절댓값
        if mini<=hap:
            break
    if hap<mini:
        mini=hap
print(mini)

feedback

float('inf')
무한수는 float형에만 적용 가능하다. int형에는 적용 불가능하다.
positive = float("inf") # 양의 무한대
print(positive)
결과:inf


✏️카카오문제 [자물쇠와 열쇠]

고고학자인 "튜브"는 고대 유적지에서 보물과 유적이 가득할 것으로 추정되는 비밀의 문을 발견하였습니다. 그런데 문을 열려고 살펴보니 특이한 형태의 자물쇠로 잠겨 있었고 문 앞에는 특이한 형태의 열쇠와 함께 자물쇠를 푸는 방법에 대해 다음과 같이 설명해 주는 종이가 발견되었습니다.

잠겨있는 자물쇠는 격자 한 칸의 크기가 1 x 1인 N x N 크기의 정사각 격자 형태이고 특이한 모양의 열쇠는 M x M 크기인 정사각 격자 형태로 되어 있습니다.
자물쇠에는 홈이 파여 있고 열쇠 또한 홈과 돌기 부분이 있습니다. 열쇠는 회전과 이동이 가능하며 열쇠의 돌기 부분을 자물쇠의 홈 부분에 딱 맞게 채우면 자물쇠가 열리게 되는 구조입니다. 자물쇠 영역을 벗어난 부분에 있는 열쇠의 홈과 돌기는 자물쇠를 여는 데 영향을 주지 않지만, 자물쇠 영역 내에서는 열쇠의 돌기 부분과 자물쇠의 홈 부분이 정확히 일치해야 하며 열쇠의 돌기와 자물쇠의 돌기가 만나서는 안됩니다. 또한 자물쇠의 모든 홈을 채워 비어있는 곳이 없어야 자물쇠를 열 수 있습니다.
열쇠를 나타내는 2차원 배열 key와 자물쇠를 나타내는 2차원 배열 lock이 매개변수로 주어질 때, 열쇠로 자물쇠를 열수 있으면 true를, 열 수 없으면 false를 return 하도록 solution 함수를 완성해주세요.

제한사항

1.key는 M x M(3 ≤ M ≤ 20, M은 자연수)크기 2차원 배열입니다.
2.lock은 N x N(3 ≤ N ≤ 20, N은 자연수)크기 2차원 배열입니다.
3.M은 항상 N 이하입니다.
4.key와 lock의 원소는 0 또는 1로 이루어져 있습니다.
- 0은 홈 부분, 1은 돌기 부분을 나타냅니다.

key를 시계 방향으로 90도 회전하고, 오른쪽으로 한 칸, 아래로 한 칸 이동하면 lock의 홈 부분을 정확히 모두 채울 수 있습니다.

code

시간은 흐르는데 어떻게 접근해야할 지 계속 막막한 문제였다. 
기본 개념이 부족한 부분도 있어서 더 그런 것 같다...
주말에 천천히 문제를 풀기위해 필요한 개념부터 살펴보아야겠다..
아 카카오 진짜 맵다 매워 ☄️

feedback

리스트-rotate() 개념.(행렬)
https://shoark7.github.io/programming/algorithm/5-ways-to-rotate-array

profile
Why.Not.Now

3개의 댓글

comment-user-thumbnail
2021년 7월 8일

안녕하세요! 😊입니다~ 카카오 문제,, 정말 매운맛 문제 같아요,, 1번 저는 잘 안되었는데 파파이썬님은 너무 잘 푸신 것 같네요!! 새로운 개념도 알아갑니다!! 알고리즘은 역시 쉽지 않네요,, 남은 문제들도 화이팅해요,,,!!

답글 달기
comment-user-thumbnail
2021년 7월 8일

안녕하세요 알고리줌입니다.
저도 자물쇠는 정말....도저히 코드를 못짜겠는 아이디어도 안떠오르는 만약 코테를 보는데
이런문제가 나오면 눈물 줄줄흘리면서 포기할것같더라고요.....
오늘 수고 많으셧습니다!

답글 달기
comment-user-thumbnail
2021년 7월 9일

안녕하세요, 김덕우입니다! 카카오 문제 정말 어렵더라고요.. 저도 주말에 다시 복습해보기로 했습니다 흑흑 어제도 너무 고생하셨습니다! 이따가 봬요!!!

답글 달기