You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
첫 줄에 부등호 문자의 개수를 나타내는 정수 k가 주어진다. 그 다음 줄에는 k개의 부등호 기호가 하나의 공백을 두고 한 줄에 모두 제시된다. k의 범위는 2 ≤ k ≤ 9 이다.
제시된 부등호 관계를 만족하는 k+1 자리의 최대, 최소 정수를 첫째 줄과 둘째 줄에 각각 출력 (모든 입력에 답은 항상 존재)
## 2529번: 부등호#### 첫 줄에 부등호 문자의 개수를 나타내는 정수 k가 주어진다. 그 다음 줄에는 k개의 부등호 기호가 하나의 공백을 두고 한 줄에 모두 제시된다. k의 범위는 2 ≤ k ≤ 9 이다. #### 제시된 부등호 관계를 만족하는 k+1 자리의 최대, 최소 정수를 첫째 줄과 둘째 줄에 각각 출력 (모든 입력에 답은 항상 존재)defnext_permutation(a):
# 1) 뒤에서부터 시작해서 처음으로 내림차순(비오름차순)을 어기는 인덱스 찾기i=len(a)-1whilei>0anda[i-1] >=a[i]:
i-=1ifi<=0: ## 종료 조건(맨 첫 숫자까지 다 돌았는데 모두 '내림차순'인 경우 => 이미 '가장 마지막 순열')returnFalse# 2) 기준점 뒤의 숫자들 중 가장 큰 수를 현재 i-1 번 숫자와 swapj=len(a)-1whilea[i-1] >=a[j]:
j-=1a[i-1], a[j] =a[j], a[i-1]
# 3) 현재 i부터 마지막까지 숫자 뒤집기j=len(a)-1whilei<j:
a[i], a[j] =a[j], a[i]
i+=1j-=1returnTruedefprev_permutation(a):
# 1) 뒤에서부터 시작해서 처음으로 내림차순(비오름차순)을 어기는 인덱스 찾기i=len(a)-1whilei>0anda[i-1] <=a[i]:
i-=1ifi<=0: ## 종료 조건(맨 첫 숫자까지 다 돌았는데 모두 '내림차순'인 경우 => 이미 '가장 마지막 순열')returnFalse# 2) 기준점 뒤의 숫자들 중 가장 큰 수를 현재 i-1 번 숫자와 swapj=len(a)-1whilea[i-1] <=a[j]:
j-=1a[i-1], a[j] =a[j], a[i-1]
# 3) 현재 i부터 마지막까지 숫자 뒤집기j=len(a)-1whilei<j:
a[i], a[j] =a[j], a[i]
i+=1j-=1returnTruedefcheck(perm, a):
foriinrange(len(a)):
ifa[i]=='<'andperm[i] >perm[i+1]:
returnFalseifa[i]=='>'andperm[i] <perm[i+1]:
returnFalsereturnTrue# 모두 만족해야 비로소 True# 입력k=int(input())
a=list(input().split()) # 입력으로 주어지는 k개의 부등호 리스트# 답 출력small= [iforiinrange(0, k+1)] # 012...k 부터 시작big= [9-iforiinrange(0, k+1)] # 987...(9-k+1) 부터 시작whileTrue: ## 최소 정수 찾기ifcheck(small, a):
break# 답 찾음ifnotnext_permutation(small):
break# 다음 순열 존재 안 할 때whileTrue: ## 최대 정수 찾기ifcheck(big, a):
break# 답 찾음ifnotprev_permutation(big):
break# 이전 순열 존재 안 할 때print(''.join(map(str, big)))
print(''.join(map(str, small)))
2
< >
897
021
big= [9-iforiinrange(0, k+1)]
big
[9, 8, 7]
<재귀>로도 구현 가능
백트래킹 쓸 수 있어, 더 빠름
## 1339번: 단어 수학#### 단어 수학 문제는 N개의 단어로 이루어져 있으며, 각 단어는 알파벳 대문자로만 이루어져 있다. 이때, 각 알파벳 대문자를 0부터 9까지의 숫자 중 하나로 바꿔서 N개의 수를 합하는 문제이다. 같은 알파벳은 같은 숫자로 바꿔야 하며, 두 개 이상의 알파벳이 같은 숫자로 바뀌어지면 안 된다.#### N개의 단어가 주어졌을 때, 그 수의 합을 최대로 만드는 프로그램을 작성하시오.# (파이썬 시간초과)defnext_permutation(a):
# 1) 뒤에서부터 시작해서 처음으로 내림차순(비오름차순)을 어기는 인덱스 찾기i=len(a)-1whilei>0anda[i-1] >=a[i]:
i-=1ifi<=0: ## 종료 조건(맨 첫 숫자까지 다 돌았는데 모두 '내림차순'인 경우 => 이미 '가장 마지막 순열')returnFalse# 2) 기준점 뒤의 숫자들 중 가장 큰 수를 현재 i-1 번 숫자와 swapj=len(a)-1whilea[i-1] >=a[j]:
j-=1a[i-1], a[j] =a[j], a[i-1]
# 3) 현재 i부터 마지막까지 숫자 뒤집기j=len(a)-1whilei<j:
a[i], a[j] =a[j], a[i]
i+=1j-=1returnTruedefcalc(a, letters, d):
m=len(letters)
ans=0# 모든 n행의 전체 합## 알파벳에 d[i] 배열 순서대로 수 배정하기 (딕셔너리 이용) alpha=dict()
foriinrange(m):
alpha[letters[i]] =d[i]
## 알파벳 별 숫자 배정에 따른 전체 수의 합forrowina:
now=0# 행에서 합forxinrow:
now=10*now+alpha[x] # 행에서 합ans+=now# 모든 n행의 전체 합returnans# 입력n=int(input())
a= [''] *nletters=set()
foriinrange(n):
a[i] =input()
letters|=set(a[i]) # |= : 연산과 동시에 할당# letters를 셋에서 리스트로 변경letters=list(letters)
m=len(letters)
d= [iforiinrange(9, 9-m, -1)] # 9876.. 부터 시작d.sort()
ans=0whileTrue:
res=calc(a, letters, d)
ifans<res:
ans=res## 최대합 비교ifnotnext_permutation(d):
breakprint(ans)
# 이전 순열 시도 (파이썬 시간초과)defprev_permutation(a):
# 1) 뒤에서부터 시작해서 처음으로 내림차순(비오름차순)을 어기는 인덱스 찾기i=len(a)-1whilei>0anda[i-1] <=a[i]:
i-=1ifi<=0: ## 종료 조건(맨 첫 숫자까지 다 돌았는데 모두 '내림차순'인 경우 => 이미 '가장 마지막 순열')returnFalse# 2) 기준점 뒤의 숫자들 중 가장 큰 수를 현재 i-1 번 숫자와 swapj=len(a)-1whilea[i-1] <=a[j]:
j-=1a[i-1], a[j] =a[j], a[i-1]
# 3) 현재 i부터 마지막까지 숫자 뒤집기j=len(a)-1whilei<j:
a[i], a[j] =a[j], a[i]
i+=1j-=1returnTruedefcalc(a, letters, d):
m=len(letters)
ans=0# 모든 n행의 전체 합## 알파벳에 d[i] 배열 순서대로 수 배정하기 (딕셔너리 이용) alpha=dict()
foriinrange(m):
alpha[letters[i]] =d[i]
## 알파벳 별 숫자 배정에 따른 전체 수의 합forrowina:
now=0# 행에서 합forxinrow:
now=10*now+alpha[x] # 행에서 합ans+=now# 모든 n행의 전체 합returnans# 입력n=int(input())
a= [''] *nletters=set()
foriinrange(n):
a[i] =input()
letters|=set(a[i]) # |= : 연산과 동시에 할당# letters를 셋에서 리스트로 변경letters=list(letters)
m=len(letters)
d= [iforiinrange(9, 9-m, -1)] # 9876.. 부터 시작ans=0whileTrue:
res=calc(a, letters, d)
ifans<res:
ans=res## 최대합 비교ifnotprev_permutation(d):
breakprint(ans)
N개의 수와 N-1개의 연산자가 주어졌을 때, 만들 수 있는 식의 결과가 최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.
첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다.
(식의 계산은 연산자 우선 순위를 무시하고 앞에서부터 진행해야 한다.)
## 14888번: 연산자 끼워넣기#### N개의 수와 N-1개의 연산자가 주어졌을 때, 만들 수 있는 식의 결과가 최대인 것과 최소인 것을 구하는 프로그램을 작성하시오.#### 첫째 줄에 수의 개수 N(2 ≤ N ≤ 11)가 주어진다. 둘째 줄에는 A1, A2, ..., AN이 주어진다. (1 ≤ Ai ≤ 100) 셋째 줄에는 합이 N-1인 4개의 정수가 주어지는데, 차례대로 덧셈(+)의 개수, 뺄셈(-)의 개수, 곱셈(×)의 개수, 나눗셈(÷)의 개수이다. defnext_permutation(a):
# 1) 뒤에서부터 시작해서 처음으로 내림차순(비오름차순)을 어기는 인덱스 찾기i=len(a)-1whilei>0anda[i-1] >=a[i]:
i-=1ifi<=0: ## 종료 조건(맨 첫 숫자까지 다 돌았는데 모두 '내림차순'인 경우 => 이미 '가장 마지막 순열')returnFalse# 2) 기준점 뒤의 숫자들 중 가장 큰 수를 현재 i-1 번 숫자와 swapj=len(a)-1whilea[i-1] >=a[j]:
j-=1a[i-1], a[j] =a[j], a[i-1]
# 3) 현재 i부터 마지막까지 숫자 뒤집기j=len(a)-1whilei<j:
a[i], a[j] =a[j], a[i]
i+=1j-=1returnTrue# (문제 조건) 또, 나눗셈은 정수 나눗셈으로 몫만 취한다. 음수를 양수로 나눌 때는 C++14의 기준을 따른다. 즉, 양수로 바꾼 뒤 몫을 취하고, 그 몫을 음수로 바꾼 것과 같다.defdiv(a, b):
ifa<0:
return-(abs(a)//b)
else:
returna//bdefcalc(a, b):
ans=a[0]
foriinrange(1, len(a)):
ifb[i-1]==0:
ans+=a[i]
ifb[i-1]==1:
ans-=a[i]
ifb[i-1]==2:
ans*=a[i]
ifb[i-1]==3:
ans=div(ans, a[i])
returnans# 입력n=int(input())
a=list(map(int, input().split())) # 입력으로 주어지는 n개의 수cnts=list(map(int, input().split())) # 사용가능한 n-1개의 각 연산자 별 갯수b= []
fori, cntinenumerate(cnts):
forkinrange(cnt):
b.append(i)
# 답 구하기ans= []
whileTrue:
temp=calc(a, b)
ans.append(temp)
ifnotnext_permutation(b):
break## 다음 순열 더이상 존재 안하면 종료print(max(ans))
print(min(ans))
3
3 4 5
1 0 1 0
35
17
<재귀>로도 구현 가능
14889번: 스타트와 링크
축구를 하기 위해 모인 사람은 총 N명이고 신기하게도 N은 짝수이다. 이제 N/2명으로 이루어진 스타트 팀과 링크 팀으로 사람들을 나눠야 한다.
스타트 팀과 링크 팀의 능력치의 차이의 최솟값을 출력한다. (팀의 능력치는 팀에 속한 모든 쌍의 능력치 Sij의 합이다. Sij는 Sji와 다를 수도 있으며, i번 사람과 j번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치는 Sij와 Sji이다.)
## 14889번: 스타트와 링크#### 축구를 하기 위해 모인 사람은 총 N명이고 신기하게도 N은 짝수이다. 이제 N/2명으로 이루어진 스타트 팀과 링크 팀으로 사람들을 나눠야 한다.#### 스타트 팀과 링크 팀의 능력치의 차이의 최솟값을 출력한다. (팀의 능력치는 팀에 속한 모든 쌍의 능력치 Sij의 합이다. Sij는 Sji와 다를 수도 있으며, i번 사람과 j번 사람이 같은 팀에 속했을 때, 팀에 더해지는 능력치는 Sij와 Sji이다.)defnext_permutation(a):
# 1) 뒤에서부터 시작해서 처음으로 내림차순(비오름차순)을 어기는 인덱스 찾기i=len(a)-1whilei>0anda[i-1] >=a[i]:
i-=1ifi<=0: ## 종료 조건(맨 첫 숫자까지 다 돌았는데 모두 '내림차순'인 경우 => 이미 '가장 마지막 순열')returnFalse# 2) 기준점 뒤의 숫자들 중 가장 큰 수를 현재 i-1 번 숫자와 swapj=len(a)-1whilea[i-1] >=a[j]:
j-=1a[i-1], a[j] =a[j], a[i-1]
# 3) 현재 i부터 마지막까지 숫자 뒤집기j=len(a)-1whilei<j:
a[i], a[j] =a[j], a[i]
i+=1j-=1returnTrue# 입력n=int(input())
s= [list(map(int, input().split())) for_inrange(n)]
# 첫 순열 만들기b= [0ifi<n//2else1foriinrange(n)] # 00...11...부터 시작ans=-1whileTrue:
# permute인 b배열에 따라 스타트, 링크 팀에 배정first= []
second= []
foriinrange(n):
ifb[i] ==0:
first.append(i)
else:
second.append(i)
# 답 구하기one=0two=0foriinrange(n//2):
forjinrange(n//2):
ifi==j:
continue# passone+=s[first[i]][first[j]]
two+=s[second[i]][second[j]]
diff=abs(one-two)
ifans==-1orans>diff:
ans=diff# 최소합 비교# 다음 순열ifnotnext_permutation(b):
break# (종료 조건)print(ans)