Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[박장우] 11주차 과제 제출합니다. #17

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 47 additions & 0 deletions 5월9일/14497/14497_python_박장우.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# 14497 주난의 난

import sys
from collections import deque
input = sys.stdin.readline

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


n, m = map(int, input().split())
graph = []
vis = [[-1] * m for _ in range(n)]
x1, y1, x2, y2 = map(int, input().split())
res = 0

for _ in range(n):
graph.append(list(map(str, input().strip())))
Comment on lines +17 to +18
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

graph = [list(input().strip()) for i in range(n)]
으로 줄일 수 있습니다.



def bfs(sx, sy):
q = deque()
q.append((sx, sy))
vis[sx][sy] = 0

while q:
x, y = q.popleft()

for i in range(4):
nx = x + dx[i]
ny = y + dy[i]

if (nx < 0 or ny < 0 or nx >= n or ny >= m) or vis[nx][ny] != -1:
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

파이썬은 0<=nx<n 같은 문법이 가능합니다.

continue

if graph[nx][ny] == '1' or graph[nx][ny] == '#':
vis[nx][ny] = vis[x][y] + 1
graph[nx][ny] = '0'
q.append((nx, ny))
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'#'일때 리턴하면 살짝 빠르게 끝낼수 있어요.


elif graph[nx][ny] == '0':
vis[nx][ny] = vis[x][y]
q.appendleft((nx, ny))


bfs(x1-1, y1-1)
print(vis[x2-1][y2-1])
58 changes: 58 additions & 0 deletions 5월9일/14575/14575_python_박장우.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# 14575 뒤풀이
import sys
input = sys.stdin.readline
INF = int(1e9)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 문제에선 크게 상관없지만, INF는 2e9나 INT_MAX값으로 잡아두면 더 좋습니다



n, t = map(int, input().split())
arr = []


def is_possible(s):
# remain: 사람들이 최소 주량만큼 마신다 가정 했을 때 더 마실 수 있는 양
# min_sum: 모든 사람들의 최소 주량 합
remain, min_sum = 0, 0

for i in range(n):

if arr[i][0] > s:
return False
Comment on lines +18 to +19
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분도 마찬가지 👍
없어도 돌아가긴 하지만 빠른 전처리에 해당됩니다~


# remain = ((최대 주량 혹은 s값 중 작은 값) - (최소 주량)) 의 합
remain += (min(arr[i][1], s) - arr[i][0])
min_sum += arr[i][0]

# t - min_sum = 사람들이 더 마셔야 하는 양
if remain >= t - min_sum:
return True

Comment on lines +26 to +28
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

따로 이렇게 처리하셨군요.
저는 min_sum과 max_sum을 각각 구한 후에, 해당 값 사이에 T가 포함되면 true를 반환하게 했답니다 😄
두 방법 모두 괜찮네요

return False


left, right = 0, 0
min_num, max_num = 0, 0
res = INF

for _ in range(n):
l, r = map(int, input().split())
min_num += l
max_num += r
right = max(right, r)
arr.append((l, r))

# 불가능한 경우
if min_num > t or max_num < t:
print(-1)
exit()
Comment on lines +44 to +46
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

아예 불가능한 경우를 빠르게 처리하셨네요 👍
이 부분은 없어도 돌아가긴 하겠지만, 장우님께서 하신 전처리 방법이 더 좋아보이네요



while left <= right:
s = (left + right) // 2
if is_possible(s):
res = min(res, s)
right = s - 1
else:
left = s + 1


print(res)
72 changes: 72 additions & 0 deletions 5월9일/1953/1953_python_박장우.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# 1953: 팀배분

import sys
from collections import deque
input = sys.stdin.readline


n = int(input())
graph = [[] for _ in range(n+1)]
vis = [0] * (n+1)

# team[0] = 청팀, team[1] = 백팀
team = [[] for _ in range(2)]

for i in range(1, n+1):
data = list(map(int, input().split()))
for j in range(1, data[0]+1):
graph[i].append(data[j])
Comment on lines +15 to +18
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분을 줄일 수 있을까요?



def is_one_sided(arr):
if len(arr) == n:
print(n-1)
for i in range(n-1):
print(arr[i], end=' ')

print()
print(1)
print(arr[-1])
exit()


def bfs(start):
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

함수 정말 잘짰네요. 👍

q = deque()
q.append(start)
vis[start] = 1

while q:
cur = q.popleft()

for person in graph[cur]:
if vis[person] != 0:
continue

if vis[cur] == 1:
vis[person] = -1
elif vis[cur] == -1:
vis[person] = 1
Comment on lines +45 to +48
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

vis[person] = -vis[cur]
로 줄일 수는 있습니다.
숏코딩에 관심있으면 해보는걸 추천드려요. ㅎㅎ


q.append(person)


for i in range(1, n+1):
if not vis[i]:
bfs(i)


for i in range(1, n+1):
if vis[i] == 1:
team[0].append(i)
else:
team[1].append(i)

team[0].sort()
team[1].sort()
Comment on lines +64 to +65
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

team이 추가되는걸 봤을때 정렬을 안해도 될 것 같아요.



is_one_sided(team[0])
print(len(team[0]))
print(*team[0])
print(len(team[1]))
print(*team[1])
65 changes: 65 additions & 0 deletions 5월9일/20313/20313_python_박장우.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
# 20313: 출퇴근
# 실패: 틀렸습니다가 계속 뜨는데 이유를 모르겠습니다.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반례하나 드릴게요.
input
3 2 1 3
1 2 1
2 3 6
2
10 4
10 1

answer
2

건물을 하나 이동하고 나서 마법을 사용할 수 있습니다.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

반례 정말정말 감사합니다!! 근데 반례를 알고도 고치는 방법이 잘 떠오르지가 않네요..


import sys
import heapq
input = sys.stdin.readline
INF = int(1e9)


n, m, a, b = map(int, input().split())
graph = [[] for _ in range(n+1)]
distance = [INF] * (n+1)
road_info = [[] for _ in range(m)]
res = INF


for i in range(m):
u, v, t = map(int, input().split())
road_info[i].append((u, v))
graph[u].append((v, t))
graph[v].append((u, t))

k = int(input())
data = []
for _ in range(k):
data.append(list(map(int, input().split())))


def dijkstra(start):

q = []
heapq.heappush(q, (0, start))
distance[start] = 0

while q:

dist, cur = heapq.heappop(q)

if dist > distance[cur]:
continue

for node in graph[cur]:
cost = dist + node[1]

if cost < distance[node[0]]:
distance[node[0]] = cost
heapq.heappush(q, (cost, node[0]))


dijkstra(a)
res = min(res, distance[b])

for i in range(k):
graph = [[] for _ in range(n+1)]
distance = [INF] * (n+1)
for j in range(m):
u, v, t = road_info[j][0][0], road_info[j][0][1], data[i][j]
graph[u].append((v, t))
graph[v].append((u, t))

dijkstra(a)
res = min(res, distance[b])


print(res, end='')
33 changes: 33 additions & 0 deletions 5월9일/23888/23888_python_박장우.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
# 23888 등차수열과 쿼리
import sys
input = sys.stdin.readline


def gcd(a, b):
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍👍
이제 유클리드 호제법을 배운지도 꽤 지났네요.

math 내장함수의 gcd를 사용해봐도 좋을 것 같아요

if a == 0:
return b

return gcd(b % a, a)


a, d = map(int, input().split())
q = int(input())
for _ in range(q):
query, l, r = map(int, input().split())
a_l = a + (l - 1) * d

if query == 1:
s_l = (2 * a + (l - 1) * d) * l // 2
s_r = (2 * a + (r - 1) * d) * r // 2
print(s_r - s_l + a_l)

# 30점 받은 코드: int 형변환 문제?
# s_l = (2 * a + (l - 1) * d) * l / 2
# s_r = (2 * a + (r - 1) * d) * r / 2
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나누는 행위는 항상 조심해야 돼요.
실제로 이 문제에선 홀*짝/2 -> 무조건 자연수이기 때문에 식을 조작하면 더 안전하게 쓸 수 있어요. (장우님께서 써주신 식이 훨씬 깔끔하지만, 오차 나기엔 더 좋다는 점 😅 )

간단한 예시를 들자면 s_l * 2와 s_r * 2의 값이 각각 8, 5라 해보죠! 100점 코드와 30점 코드에는 각각 어떤 차이가 있을까요?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

나누는 행위는 항상 조심해야 돼요. 실제로 이 문제에선 홀*짝/2 -> 무조건 자연수이기 때문에 식을 조작하면 더 안전하게 쓸 수 있어요. (장우님께서 써주신 식이 훨씬 깔끔하지만, 오차 나기엔 더 좋다는 점 😅 )

간단한 예시를 들자면 s_l * 2와 s_r * 2의 값이 각각 8, 5라 해보죠! 100점 코드와 30점 코드에는 각각 어떤 차이가 있을까요?

100점 코드에서는 정수 부분끼리 계산했을 때 s_r = 4, s_l = 2로 계산되어 답이 4 - 2 + a_l 로 출력되겠지만
30점 코드에서는 s_r - s_l = 4 - 2.5 = 1.5 로 계산되어 최종 답이 int(1.5) + a_l = 1 + a_l이 되겠네요.
나누는 행위에서 소수를 고려하지 않았었던 것 같아요. 감사합니다!

# print(int(s_r - s_l) + a_l)

else:
if l == r:
print(a_l)
else:
print(gcd(a, d))