Part 3,実施
インプリメンテーション
実施:頭の中のアルゴリズムを正確で迅速なプログラムに編成する.
実装能力の要件を有する典型的なアルゴリズム問題タイプであり,終点探索とシミュレーションがある.
完全なナビゲーション:これは、すべての状況ですべての数を計算できるソリューションを意味します.
解決策は、
標準ライブラリitertools
リストされたすべての要素の数を考慮する必要がある場合、通常、シーケンスまたはコンビネーションライブラリを使用するときにitertoolsを使用して実装されます.
ソースコードが実現しにくい、複雑な文字列を処理する必要がある、または実装する必要がある大量のソースコードの問題を実装タイプに分ける.
[Q 07]ラッキーストレート
n = input()
front_n = n[0:len(n)//2]
back_n = n[len(n)//2:len(n)]
front_n = map(int,front_n)
back_n = map(int,back_n)
result_f = sum(front_n)
result_b = sum(back_n)
if result_f == result_b:
print('LUCKY')
else:
print('READY')
[Q 08]並べ替え文字列
リストを文字列に変換
A = ['a','b','c']
stra = ''.join(A)
print(stra)
ソースs = input()
alpa = []
sum = 0
for i in range(len(s)):
if '1' <= s[i] and s[i] <= '9':
sum += int(s[i])
else:
alpa.append(s[i])
alpa.sort()
alpa.append(str(sum))
print(''.join(alpa))
[Q 09]文字列圧縮
def solution(s):
answer = 0
total = ''
result = ''
for i in range(1, len(s)//2+1):
check_in_s = s[:i]
cnt = 1
result = ''
# print("i : ",i,end = " ")
for j in range(i,len(s),i):
# print("j : ",j,end = " ")
check_after_s = s[j:i+j]
# print("after_s : ",check_after_s, end=" ")
if check_in_s == check_after_s:
cnt += 1
else:
if cnt > 1:
result += str(cnt) + check_in_s
else:
result += check_in_s
check_in_s = check_after_s
cnt = 1
# print("result : ",result, end=" ")
# print()
if cnt > 1:
result += str(cnt) + check_in_s
else:
result += check_in_s
# print("result : ",len(result), " ",result)
# print()
if total == '' or len(total) > len(result):
total = result
answer = len(total)
if answer == 0:
answer = 1
return answer
[Q 10]ロックとキー
やるべきこと:キーを適切に回して移動し、ロックスロットに挿入します.
アクセスサイズが20 x 20の2 Dリスト内のすべての要素にアクセスするには、400の演算量が必要です.
完全ナビゲーションを使用してキーを移動または回転させ、キーをすべてロックに挿入する操作を試みることができます.
例では
の場合、
は、です.
空白に鍵をかけるとドアが開きます.
ロックについてすべての状況を確認すればいい.
完全なナビゲーションを容易にするために、ロックリストのサイズを3倍以上に変更すると、計算が容易になります.
鍵と鍵の大きさが3*3の場合、まず鍵を3倍の大きさの新しいリストとして、中央部分に移動します.
次に、左上からグリッドを1つずつ移動して、ロックされたすべての溝を順番に充填できるかどうかを確認します.
0:ホームページ、1:回転部分
ロックリストにキーリストの値を追加した後、追加の結果を確認するには、ロック部分のすべての値が1であることを確認するだけです.
すべての値が1である場合、ロックの溝部分が正しく充填されます.
ソースで使用するrotate a matrix by 90度()メソッド
:2 Dリストを90度回転させた結果を返す方法(Pythonで2 Dリストを処理する際にたまに使用)
# 2차원 리스트 90도 회전
def rotate_a_matrix_by_90_degree(a):
n = len(a) # 행 길이 계산
m = len(a[0]) # 열 길이 계산
result = [[0] * n for _ in range(m)] # 결과 리스트
for i in range(n):
for j in range(m):
result[j][n - i - 1] = a[i][j]
return result
# 자물쇠의 중간 부분이 모두 1인지 확인
def check(new_lock):
lock_length = len(new_lock) // 3
for i in range(lock_length, lock_length * 2):
for j in range(lock_length, lock_length * 2):
if new_lock[i][j] != 1:
return False
return True
def solution(key, lock):
n = len(lock)
m = len(key)
# 자물쇠의 크기를 기존의 3배로 변환
new_lock = [[0] * (n * 3) for _ in range(n * 3)]
# 새로운 자물쇠의 중앙 부분에 기존의 자물쇠 넣기
for i in range(n):
for j in range(n):
new_lock[i + n][j + n] = lock[i][j]
# 4가지 방향에 대해서 확인
for rotation in range(4):
key = rotate_a_matrix_by_90_degree(key) # 열쇠 회전
for x in range(n * 2):
for y in range(n * 2):
# 자물쇠에 열쇠를 끼워 넣기
for i in range(m):
for j in range(m):
new_lock[x+i][y+j] += key[i][j]
# 새로운 자물쇠에 열쇠가 정확히 들어맞는지 검사
if check(new_lock) == True:
return True
# 자물쇠에서 열쇠를 다시 빼기
for i in range(m):
for j in range(m):
new_lock[x + i][y + j] -= key[i][j]
return False
# 강의 영상 : https://youtu.be/RrWnBaflV2o
def match(arr, key, rot, r, c):
n = len(key)
for i in range(n):
for j in range(n):
# 회전 값이 없다면 그대로 복사한다.
# 이외는 회전한다.
if rot == 0:
arr[r + i][c + j] += key[i][j]
elif rot == 1:
arr[r + i][c + j] += key[n - 1 - j][i]
elif rot == 2:
arr[r + i][c + j] += key[n - 1 - i][n - 1 - j]
else:
arr[r + i][c + j] += key[j][n - 1 - i]
def check(arr, offset, n):
for i in range(n):
for j in range(n):
if arr[offset+ i][offset + j] != 1:
return False
return True
def solution(key, lock):
offset = len(key) - 1
# key * key 크기의 사각형에서
# offset은 겹치는 부분 제외 나머지 부분
for r in range(offset + len(lock)):
for c in range(offset + len(lock)):
for rot in range(4):
# 90도 방향으로 돌려본다. (4번을 돌리게 된다.)
# 열쇠 같은 경우 최대 가로 20, 20, 20 세로 20, 20, 20
# 최대한 하나는 겹쳐야 하므로 key 양쪽 끝 2개를 제외함으로
# 60 - 2 = 58개가 필요하다.
arr = [[0 for _ in range(58)] for _ in range(58)]
# 자물쇠를 offset만큼 떨어진 위치에 복사한다.
for i in range(len(lock)):
for j in range(len(lock)):
arr[offset + i][offset + j] = lock[i][j]
# r, c, rot를 통하여 열쇠를 복사한다.
match(arr, key, rot, r, c)
if check(arr, offset, len(lock)):
return True
return False
k = [[0,0,0],[1,0,0],[0,1,1]]
lock = [[1,1,1],[1,1,0],[1,0,1]]
solution(k, lock)
[Q 11]ヘビ
n = int(input())
k = int(input())
data = [[0] * (n + 1) for _ in range(n + 1)] # 맵 정보
info = [] # 방향 회전 정보
# 맵 정보(사과 있는 곳은 1로 표시)
for _ in range(k):
a, b = map(int, input().split())
data[a][b] = 1
# 방향 회전 정보 입력
l = int(input())
for _ in range(l):
x, c = input().split()
info.append((int(x), c))
# 처음에는 오른쪽을 보고 있으므로(동, 남, 서, 북)
dx = [0, 1, 0, -1]
dy = [1, 0, -1, 0]
def turn(direction, c):
if c == "L":
direction = (direction - 1) % 4
else:
direction = (direction + 1) % 4
return direction
def simulate():
x, y = 1, 1 # 뱀의 머리 위치
data[x][y] = 2 # 뱀이 존재하는 위치는 2로 표시
direction = 0 # 처음에는 동쪽을 보고 있음
time = 0 # 시작한 뒤에 지난 '초' 시간
index = 0 # 다음에 회전할 정보
q = [(x, y)] # 뱀이 차지하고 있는 위치 정보(꼬리가 앞쪽)
while True:
nx = x + dx[direction]
ny = y + dy[direction]
# 맵 범위 안에 있고, 뱀의 몸통이 없는 위치라면
if 1 <= nx and nx <= n and 1 <= ny and ny <= n and data[nx][ny] != 2:
# 사과가 없다면 이동 후에 꼬리 제거
if data[nx][ny] == 0:
data[nx][ny] = 2
q.append((nx, ny))
px, py = q.pop(0)
data[px][py] = 0
# 사과가 있다면 이동 후에 꼬리 그대로 두기
if data[nx][ny] == 1:
data[nx][ny] = 2
q.append((nx, ny))
# 벽이나 뱀의 몸통과 부딪혔다면
else:
time += 1
break
x, y = nx, ny # 다음 위치로 머리를 이동
time += 1
if index < l and time == info[index][0]: # 회전할 시간인 경우 회전
direction = turn(direction, info[index][1])
index += 1
return time
print(simulate())
[Q 12柱とビーム取り付け]
コマンド総数:M(1000個未満)
時間の複雑さ:Bigo(M^2)、時間は5秒に制限され、Bigo(M^3)を使用できます.
柱と梁を重点とする
柱に隣接すれば梁を立てることができる.
動画リスト
インストールと削除操作が要求されるたびに、構造全体を確認し、ルールを確認します.
かのう()ほうほう
正常でない場合、現在の演算は無視されます.
# 현재 설치된 구조물이 '가능한' 구조물인지 확인하는 함수
def possible(answer):
for x, y, stuff in answer:
if stuff == 0: # 설치된 것이 '기둥'인 경우
# '바닥 위' 혹은 '보의 한쪽 끝부분 위' 혹은 '다른 기둥 위'라면 정상
if y == 0 or [x - 1, y, 1] in answer or [x, y, 1] in answer or [x, y - 1, 0] in answer:
continue
return False # 아니라면 거짓(False) 반환
elif stuff == 1: # 설치된 것이 '보'인 경우
# '한쪽 끝부분이 기둥 위' 혹은 '양쪽 끝부분이 다른 보와 동시에 연결'이라면 정상
if [x, y - 1, 0] in answer or [x + 1, y - 1, 0] in answer or ([x - 1, y, 1] in answer and [x + 1, y, 1] in answer):
continue
return False # 아니라면 거짓(False) 반환
return True
def solution(n, build_frame):
answer = []
for frame in build_frame: # 작업(frame)의 개수는 최대 1,000개
x, y, stuff, operate = frame
if operate == 0: # 삭제하는 경우
answer.remove([x, y, stuff]) # 일단 삭제를 해본 뒤에
if not possible(answer): # 가능한 구조물인지 확인
answer.append([x, y, stuff]) # 가능한 구조물이 아니라면 다시 설치
if operate == 1: # 설치하는 경우
answer.append([x, y, stuff]) # 일단 설치를 해본 뒤에
if not possible(answer): # 가능한 구조물인지 확인
answer.remove([x, y, stuff]) # 가능한 구조물이 아니라면 다시 제거
return sorted(answer) # 정렬된 결과를 반환
[Q 13から揚げ]
問題を理解する
0:スペース、1:家、2:フライドチキン屋
既存のフライドチキン店を減らし、最大でM個を維持し、一般店からM個のフライドチキン店までの距離を減らすことを目標としている.
その後、都市フライドチキン街協定の最高価格を計算すればいいです.
例の結果は次のとおりです.
フライドチキン店個数範囲:M<=フライドチキン店個数<=13
フライドチキン屋でM個セットを選べば(Combinations)
最大13個からM個を選択した組み合わせと同じである.
13 CMの値は100000を超えない.
家の数は最大でも100個あるので、すべての場合の数を計算しても、タイムアウトせずに問題を解決できます.
Pythonはコンビネーションライブラリを提供しています
それを利用してすべての状況を簡単に計算することができます.
フライドチキン店でM個を選ぶ場合は、フライドチキン距離の和(完全探索)を算出し、フライドチキン距離の最高価格を求めて出力すればよい.
5 2
0 2 0 1 0
1 0 1 0 0
0 0 0 0 0
2 0 0 1 1
2 2 0 1 2
candidates 결과 예시
[((0, 1), (3, 0)), ((0, 1), (4, 0)), ((0, 1), (4, 1)), ((0, 1), (4, 4)), ((3, 0), (4, 0)), ((3, 0), (4, 1)), ((3, 0), (4, 4)), ((4, 0), (4, 1)), ((4, 0), (4, 4)), ((4, 1), (4, 4))]
ソース
from itertools import combinations
n, m = map(int, input().split())
chicken, house = [], []
for r in range(n):
data = list(map(int, input().split()))
for c in range(n):
if data[c] == 1:
house.append((r, c)) # 일반 집
elif data[c] == 2:
chicken.append((r, c)) # 치킨 집
# 모든 치킨집 중에서 m개의 치킨집을 뽑는 조합 계산
candidates = list(combinations(chicken, m))
# 치킨 거리의 합을 계산하는 함수
def get_sum(candiate):
result = 0
# 모든 집에 대하여
for hx, hy in house:
# 가장 가까운 치킨집을 찾기
temp = 1e9
for cx, cy in candiate:
temp = min(temp, abs(hx - cx) + abs(hy - cy))
# 가장 가까운 치킨집까지의 거리를 더하기
result += temp
# 치킨 거리의 합 반환
return result
# 치킨 거리의 합의 최소를 찾아 출력
result = 1e9
for candiate in candidates:
result = min(result, get_sum(candiate))
print(result)
[Q 14外壁をチェック]
n:外壁長
弱い部分:弱い部分の位置
dist:友人1時間あたりの移動距離を含む配列
弱いリストとdistリストの長さは小さい.
指定されたデータが少ない場合は、完全なナビゲーションを使用してすべての状況にアクセスしようとします.
質問から探す値:入力する必要がある友人数の最大値
最大友達数:8(dist長さ最大値)
すべての友人のすべてのシーケンスの数をランダムにリストします:8 P 8=8!=計算可能な40320数量
(シーケンス:Permutations)
from itertools import permutations
arr = ['A', 'B', 'C']
nPr = permutations(arr, 2)
print(list(nPr))
# 결과
# [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
友人をリストする場合は、それぞれ数を確認し、少なくとも何人かの友人を手配する必要があると計算すると、問題を解決することができます.
しかし、問題では、弱点は原型で構成されていると説明している.
リストされたデータを処理する場合、問題解決を簡略化するために、長さを2倍に増やして「円形」を1文字にすることができます.
ex) n : 12, weak : [1, 3, 4, 9, 10], dist : [3m, 5m, 7m], result : 1
脆弱な場所を2回羅列し、「円形」を1文字にする.メンテナンス時間1時間(n:12)
友達の数を羅列する中で[7 M,3 M,5 M]
移動7 mの友人が9 mポイントから5カ所を訪問すれば、移動7 mですべての弱点をチェックすることができます.
ソース
from itertools import permutations
def solution(n, weak, dist):
# 길이를 2배로 늘려서 '원형'을 일자 형태로 변형
length = len(weak)
for i in range(length):
weak.append(weak[i] + n)
answer = len(dist) + 1 # 투입할 친구 수의 최솟값을 찾아야 하므로 len(dist) + 1로 초기화
# 0부터 length - 1까지의 위치를 각각 시작점으로 설정
for start in range(length):
#print()
#print("시작지점(start) : ", start)
# 친구를 나열하는 모든 경우의 수 각각에 대하여 확인
for friends in list(permutations(dist, len(dist))):
#print("friends : ", friends, end=' ')
count = 1 # 투입할 친구의 수
# 해당 친구가 점검할 수 있는 마지막 위치
position = weak[start] + friends[count - 1]
#print("친구가 점검할 수 있는 마지막 위치 : ", position, ":", weak[start], "+", friends[count - 1])
# 시작점부터 모든 취약 지점을 확인
#print("시작점 부터 모든 취약지점을 확인", start, start + length)
for index in range(start, start + length):
# 점검할 수 있는 위치를 벗어나는 경우
if position < weak[index]:
#print("현재 index", index, "해당 친구가 점검할 수 있는 마지막 위치 < 취약한 지점 :", position, weak[index], end =' ')
count += 1 # 새로운 친구를 투입
#print("새로운 친구를 투입")
if count > len(dist): # 더 투입이 불가능하다면 종료
#print("새로운 친구 명수가, 총 투입될 수 있는 인원수 보다 많아 종료")
break
position = weak[index] + friends[count - 1]
#print("새로운 친구가 점검할 수 있는 마지막 위치 업데이트 : ", position,":",weak[index]," + ",friends[count-1], " index, count : ", index, count)
answer = min(answer, count) # 최솟값 계산
#print("결과 : ", answer)
if answer > len(dist):
return -1
return answer
参考資料
Reference
この問題について(Part 3,実施), 我々は、より多くの情報をここで見つけました https://velog.io/@chang626/Part3-구현テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol