2024.04-2
4월 3주차 기록
2024년 4월 10일
1. 11650번 좌표정렬하기
바로 푼 문제!
import sys
num = int(input())
nums=[]
for idx in range(num):
x, y =map(int,sys.stdin.readline().strip().split())
nums.append([x,y])
nums.sort(key = lambda x: (x[0],x[1]))
for i in nums:
print(i[0],i[1])
2. 11866번 요세푸스 문제 0
리스트에서 요소를 제거하면 되겠다! 라는 생각이 들었는데 어떤 식인지 감이 안잡혀서 틀렸다 ㅠㅠ
고려할 점은, pop에서 사람들이 제거되니, list의 길이가 줄어드므로 index에서 그만큼의 나머지를 구해줘야 함! 즉 index에서 k를 더해주고 (몇번 마다 해야할지) 그리고 그건 index니까 1빼주고 !
(index +k-1)%len(nums)이 된다.
알게 된 점
- print() 에서 속성! print(~~~ , sep =’’)으로 적용. 구분자! end는 저 프린트에서 마지막만 넣어줌.
- print(”{0}월 {1}일”.format(10,20)) 으로 넣거나 %s:문자열, %d 정수로도 가능
- fstring기능! f’
{a}{b}’로 하고 a=10 b= 10으로 하면 들어간다.
import sys
n,k = map(int,sys.stdin.readline().strip().split())
nums= [i for i in range(1,n+1)]
index= 0
sortList = []
for i in range(n):
index = (index +k-1)%len(nums)
sortList.append(str(nums.pop(index)))
print('<',', '.join(sortList),'>', sep='')
3. 2231번 분해합
아니 왜 계속 시간초과나는지 고민 ㅠㅠ
왜 오류뜨는거지.. 그 이유를 자연수가 아닌 곳에서 찾음 ^^
알게 된 점
- 일단 map(int,str(123))로 하면 [1,2,3]으로 변형되어 나온다! 하나하나 적용돼서 나오는 듯. 여기서 계속 오류난건, 자릿수 최대로 -9*digit 해줫는데 마이너스가 나올 생각을 못함..! 그래서 마이너스가 int로 적용은 되는 느낌인데 str로 바꾸고 이걸 각각 map으로 int를 적용시키면 굳이 list로 안감싸도 다 분리돼서 적용된다. 근데 이때 -1 이런게 들어가면 적용을 못함.. 생각해보면 -12을 str로 바꾸고 각자 int로 넣으려고 하면 객체 자체는 만들어지나, 값에 접근하려고 하면 에러 뜬다. 걍 쓰지말자!
- 생각해보면 -12를 - , 1, 2로 분리하지않을까.. 그러면 -라는 숫자가 없으니 접근하면 에러나는건 아닌지..
나의 코드
import sys
found = False
nums = input()
n = int(nums)
findNum = n-(len(nums)*9)
if findNum<0:
findNum = 0
while findNum<n:
if sum(map(int,str(findNum)))+findNum==n:
print(findNum)
found = True
break
findNum+=1
if not found:
print(0)
4. 2292 벌집
무난 무난하게 풀었다! 벌집이니까 6,12,18 이 순서로 차이나서 이것을 기준으로 level을 나누고, 어떤 레벨인지 출력했다! 중간에 7인경우 1+6이라 2레벨인데 3레벨로 떠서 코드 변경했다. 이때는 sums=1로 둬서 1을 기준으로 나누게 했다
나의 코드
n = int(input())
nofound =True
count =1
sums= 1
while(nofound):
if n ==1:
print(1)
nofound = False
break
else:
sums += count*6
count +=1
if sums>=n:
print(count)
nofound = False
break
코드비교
- 다른 사람이랑 다른건 딱히 없고 다만 while문에서 종료 조건이 다르다는 것? 비교하는 숫자보다 증가하는 값이 커질 때 사실 종료하면 되더라..^^
4. 15829번 Hashing
문제에서 지시하는 대로 풀었고, Hashing에 대해 더 알아야 겠다고 생각 함.
처음에 50점 나온건, 1234567891의 서로소로 mod(나머지)를 구하지 않고 제출했기 때문에..! 충돌 방지 위해서 나누는 거라고 함.
알게 된 것
- Hashing- 알파벳 마다, 아니면 값마다 고유 값을 생성, 근데 출력이 무한이면 안되니까 적당히 큰 수로 나머지를 구하면 됨. 그러나 비둘기 집 원리로, 어쨌든 같은 Hash값을 가지는 두 개의 값이 생겨날 가능성 있음.
- 비둘기 집의 원리: K+1개의 물체를 K 개 상자에 넣으면, 적어도 하나의 상자에는 두 개 이상의 물체가 들어간다.
- 충돌 해결 위해 번호마다 특정 값을 매기는 것임! 즉, 순서에 따라서 달라지게 해야함. 그러면 첫번째 두번째가 같은 hash값을 가지는 것도 , 첫째는 1을 더 더해주거나 둘째는 2를 더 더해주면 값이 변하게 되어 충돌 회피가 가능하다. 이를 위해, 각 값마다 고유한 계수를 부여! 이건 번호에 해당하는 만큼의 특정 숫자를 거듭제곱해서 곱하고 더해주면 된다. H
2024년 4월 11일
1. 2775번 부녀회장이 될테야
뭔가 2차원 리스트로 풀면 되겠다고 생각했는데 구현이 너무 막혔다. 시간이 너무 걸려서 그냥 답을 보게 되었다.
구현코드
t = int(input())
for i in range(t):
kFloor = int(input())
n = int(input())
floor = [x for x in range(1,n+1)]
for k in range(kFloor):
for i in range(1,n):
floor[i] += floor[i-1]
print(floor[-1])
- 2869번 달팽이는 올라가고 싶다
2024년 4월 13일
그냥 while문으로 풀어볼까 했다가 3번 예시에서 오래걸리는 거 보고 바로 접음. 어떻게든 수학식으로 풀 수 있을 것 같아서 해봤다.
처음엔 단순히 v//(a-b)로 접근하다가 3번 예시로 안되는 걸 알았음. (근데 이건 예시 없이도 내가 미리 예외를 생각했어야 했는데 생각이 짧았다. ) 그리고 어떻게 해야 정상에 올라갔을때 떨어지지 않을 예를 생각할까 해서 고민하다가 v-a로 미리 올라간 상황을 상정하기로 함. 근데 여기에서 문제는 1.2처럼 나머지가 남았을때는 day를 +1해줘야하는데 그걸 하기가 어려워서.. 나머지가 있을 때 if문을 +1을 해줘야 하나 했지만 걍 math.ceil로 처리했다.
구현코드
import sys
import math
a,b,v= map(int,sys.stdin.readline().strip().split())
print(math.ceil((v-a)/(a-b)+1))
2.10989번 수 정렬하기 3
그저 받고 sort()하는 것 만으로는 메모리 초과가 뜬다. 그래서 extend로 하려 했더니 그것도 메모리 초과가 뜬다. 결국 해결하지못하고 봤다.
알게 된 점
- append()를 반복할수록 느려진다. 블로그 보고 잠깐 헷갈렸는데 우선, append()나 extend()나 둘 다 리스트의 주소값은 상관이 없다. 그저 append()는 기존에 있는 메모리에 자리가 없을 경우, 새롭게 공간을 만들어 모든 값을 이사시켜야한다. 이때 오버헤드 발생하여 느려진다!! → 이를 해결하기 위해선, 미리 N개의 공간을 만들어두고 값만 바꿔주면, 시간을 1.5배 줄일 수 있다. by.참고 블로그
구현코드
import sys
n = int(input())
numList= [0] * 10001 #미리 공간을 형성하여 오버헤드를 막아줌
for i in range(n):
nums = int(sys.stdin.readline()) #여기서 Strip으로 개행문자를 없애나 똑같음
numList[nums] +=1 # key를 value에 넣는 게 아닌 index에 넣었다.
for i in range(10001):
if numList[i] != 0: #즉 숫자가 위에서 불려졌다면,
for j in range(numList[i]): #counting된 만큼
sys.stdout.write(str(i)+'\n') #index = key를 str로 출력해라.
-
2024년 4월 14일
목표! 5문제 이상 풀기. 시간 30~40분 정하고 풀기.
1. 1436번 영화감독 숌
원래 생각하던건 숫자를 하나하나 더해서 666이 있으면 count를 증가하려고 했는데 in이 오래걸릴 것 같아 다른 방법을 생각했다. 예를 들어 10까지 하나씩 증가 시키는데, 66610, 16660이나 66610 이 세개를 for문으로 돌아 가장 작은것을 얻고, check를 하여 이미 본 숫자인지 본다. 근데 이러면 그 for문 이후에 11이 되어 10이 들어가는 3가지 케이스를 전부다 보지 못하게 된다. 원래 해보고 싶었던 걸로 할걸 그랬다!
구현코드
n = int(input())
#종말의 수 = 6이 적어도 3개 이상 들어가는 수
count =0
num = 0
while(count<n):
if '666' in str(num):
count +=1
if count ==n:
break
num+=1
print(num)
2. 1676번 팩토리얼 0의 개수
처음에는 문제 자체를 이해 못해서 이해하느라 오래 걸렸다.. 이후 Split으로 나눠보고 나눠진 부분이 ‘’으로 남는 것을 활용ㅇ하려 했으나 그 앞에도 00이 겹치면 ‘’이라 뜨기 때문에 옳지 않은 방법이었다. 이후 역순으로 바꿔서 다음 값과 다른지 비교해 보는것으로 풀었다!
구현코드
import math
N = int(input())
result = str(math.factorial(N))
if result[-1] =='0':
for i in range(len(result)-2):
if result[::-1][i] != result[::-1][i+1]:
print(i+1)
break
else:
print(0)
.
3.7568번 덩치
꽤나 골머리를 앓았다. 일단 문제 해석을 잘못했다. 나의 등수만 고집해서 틀렸다.. 그냥 나보다 덩치가 큰 사람이 얼마나 있냐 라는 게 취지였다. 그리하여 for문을 돌아, 나보다 큰 사람이 얼마나 있는지 확인했다. 50명 밖에 없으니 for문을 돌아도 시간이 될것 같았다.
코드비교
다른 사람들은 더 간단히 구현했다. 굳이 sort()를 할 필요 없이, 어차피 for문으로 전부 다 비교 하므로 for문을 두개 돌아서 나보다 큰 경우만 추가해줬다. 이때 내가 중복되어도 어차피 크다고 쳐지지 않으므로 중복으로 for문을 돌아도 괜찮다.
for me in pool: #pool은 [키,몸무게]로 이루어짐.
rank = 1 #me일때 for문을 추가로 돌아야 굳이 순서 변경없이 그대로 출력 가능
for other in pool:
if me[0] < other[0] and me[1] < other[1]:
rank += 1
print(rank, end=' ')
구현코드
import sys
N = int(input())
people = []
result = []
for i in range(N):
x,y = map(int,sys.stdin.readline().strip().split())
people.append([x+y,x,y,i])
people.sort(reverse=True)
for idx in range(len(people)):
bigger_count = 1
for j in range(0,idx):#제일 큰놈부터 나 전까지
if people[j][1]>people[idx][1] and people[j][2]>people[idx][2]:
bigger_count+=1
result.append([people[idx][3],bigger_count])
result.sort()
for i in result:
print(i[1])
4. 11651번 좌표 정렬하기 2
딱 보자마자 이제껏 계속 본 문제 아닌가 싶었다. 그런데 2차원 리스트를 밖에서 한번에 풀고 싶어서 sum(list,[]) 이런 것도 해봤지만 잘 안됐다 ㅠㅠ
코드 비교
신기한 건 sys.stdin.readlines()[1:]으로 한번에 불러 들여서 split으로 나눈 뒤, 그의 [1]값과 [0]값을 lamda로 돌리니까 바르던데 왜 vscode에선 그게 잘 안돌아가는 지 모르겠다 ㅠ
+) 추가! Ctrl+Z하니까 된다!
구현코드
import sys
N = int(input())
location =[]
for i in range(N):
x,y = map(int,sys.stdin.readline().strip().split())
location.extend([[x,y]])
location.sort(key=lambda x: (x[1],x[0]))
for i in location:
print(i[0],i[1])
5. 4949번 균형잡힌 세상
일단 괄호가 중요하기에 알파벳을 다 없애자고 생각했다. 그래서 replace를 통해 찾은 모든 문자를 지웠다. 소문자, 대문자, 공백 순으로 지우고, 소괄호 대괄호를 최대한 지웠다.
구현코드
from string import ascii_lowercase
from string import ascii_uppercase
import sys
sentence = sys.stdin.readlines()
for a in sentence:
if a =='.\n':
break
for lower in ascii_lowercase:
a= a.replace(lower,"") #소문자 제거
for upper in ascii_uppercase:
a = a.replace(upper,"") #대문자 제거
a = a.replace(" ","") #공백 제거
for i in range(len(a)):
a = a.replace('()','') #계속 반복하여 제거
a = a.replace('[]','')
if a.strip()=='.': #다 지워졌으면 균형잡힌 것
print('yes')
else:
print('no')