문제 설명

여러 개의 쇠막대기를 레이저로 절단하려고 한다. 효율적인 작업을 위해서 쇠막대기를 아래에서 위로 겹쳐 놓고, 레이저를 위에서 수직으로 발사하여 쇠막대기들을 자른다. 쇠막대기와 레이저의 배치는 다음 조건을 만족한다.

  • 쇠막대기는 자신보다 긴 쇠막대기 위에만 놓일 수 있다. - 쇠막대기를 다른 쇠막대기 위에 놓는 경우 완전히 포함되도록 놓되, 끝점은 겹치지 않도록 놓는다.
  • 각 쇠막대기를 자르는 레이저는 적어도 하나 존재한다.
  • 레이저는 어떤 쇠막대기의 양 끝점과도 겹치지 않는다.

아래 그림은 위 조건을 만족하는 예를 보여준다. 수평으로 그려진 굵은 실선은 쇠막대기이고, 점은 레이저의 위치, 수직으로 그려진 점선 화살표는 레이저의 발사 방향이다.

이러한 레이저와 쇠막대기의 배치는 다음과 같이 괄호를 이용하여 왼쪽부터 순서대로 표현할 수 있다.

  1. 레이저는 여는 괄호와 닫는 괄호의 인접한 쌍 ‘( ) ’ 으로 표현된다. 또한, 모든 ‘( ) ’는 반드시 레이저를 표현한다.
  2. 쇠막대기의 왼쪽 끝은 여는 괄호 ‘ ( ’ 로, 오른쪽 끝은 닫힌 괄호 ‘) ’ 로 표현된다.

위 예의 괄호 표현은 그림 위에 주어져 있다.

쇠막대기는 레이저에 의해 몇 개의 조각으로 잘려지는데, 위 예에서 가장 위에 있는 두 개의 쇠막대기는 각각 3개와 2개의 조각으로 잘려지고, 이와 같은 방식으로 주어진 쇠막대기들은 총 17개의 조각으로 잘려진다.

쇠막대기와 레이저의 배치를 나타내는 괄호 표현이 주어졌을 때, 잘려진 쇠막대기 조각의 총 개수를 구하는 프로그램을 작성하시오.

입력

한 줄에 쇠막대기와 레이저의 배치를 나타내는 괄호 표현이 공백없이 주어진다. 괄호 문자의 개수는 최대 100,000이다.

출력

잘려진 조각의 총 개수를 나타내는 정수를 한 줄에 출력한다.


문제해석

  • 쇠막대기와 레이저가 괄호로 표현되면서 순서대로 입력된다. 
  •  ')'를 찾았다면, 이전의 '(' 중에서도 ')'와 가장 가까운 '('와 짝을 맺어야 쇠막대기 하나가 된다.

그렇기 때문에 자료구조 스택을 사용한다.

 

ans라는 조각 수를 저장하는 변수,

현재까지 만들어질 예정인 막대기들 시작점을 담는 스택을 두자.

  • '(' 이라면, 스택에 넣는다.  
  • 순차적으로 입력값을 돌면서 '()'인 레이저를 찾았다면 개수는 ans += (현재 막대기의 수)이 된다.
  • ')'를 찾아서 막대기가 완성됐다면 꼬다리 조각 하나가 채워지기 때문에 ans += 1

 

입력값을 순차적으로 생각하지 않고 쇠막대기들이 중첩으로 쌓여있는 상태로, 전체적인 그림으로만 생각이 갇혔던 것 같다. 그래서 와.. 중첩으로 쌓여있는 쇠막대기들은 어떻게 구분해서 계산해야 하지? 고민이 들었다.

 

하지만 입력받은 값을 순차적으로 생각해가면서 논리를 따져보니, 중첩된 막대기수에 대한 풀이는 별 고려사항이 안 된것 같다.

 

코드

import sys
input = sys.stdin.readline().strip

ans = 0
st = []

brackets = list(input())

for i in range(len(brackets)):
  if(brackets[i] == '('):
    st.append("(")
  
  else:
    if(brackets[i-1] == '('): # 레이저!
      st.pop()
      ans += len(st)
    
    else: # 막대기 완성됨
      st.pop()
      ans += 1

print(ans)

 

코테 공부 많이 해야할 것 같다...!

'알고리즘 공부 > coding test' 카테고리의 다른 글

백준 17413 [단어 뒤집기 2]  (0) 2022.09.16
백준 1931 [회의실 배정]  (0) 2022.05.20
백준 20115 [에너지 드링크]  (0) 2022.05.20
백준 11399 [ATM]  (0) 2022.05.18
백준 2217[로프]  (0) 2022.05.17

문제 설명

문자열 S가 주어졌을 때, 이 문자열에서 단어만 뒤집으려고 한다.

먼저, 문자열 S는 아래와과 같은 규칙을 지킨다.

  1. 알파벳 소문자('a'-'z'), 숫자('0'-'9'), 공백(' '), 특수 문자('<', '>')로만 이루어져 있다.
  2. 문자열의 시작과 끝은 공백이 아니다.
  3. '<'와 '>'가 문자열에 있는 경우 번갈아가면서 등장하며, '<'이 먼저 등장한다. 또, 두 문자의 개수는 같다.

태그는 '<'로 시작해서 '>'로 끝나는 길이가 3 이상인 부분 문자열이고, '<'와 '>' 사이에는 알파벳 소문자와 공백만 있다. 단어는 알파벳 소문자와 숫자로 이루어진 부분 문자열이고, 연속하는 두 단어는 공백 하나로 구분한다. 태그는 단어가 아니며, 태그와 단어 사이에는 공백이 없다.

입력

첫째 줄에 문자열 S가 주어진다. S의 길이는 100,000 이하이다.

출력

첫째 줄에 문자열 S의 단어를 뒤집어서 출력한다.

해결법

1. 입력받은 문자열을 먼저 리스트로 변환

2. 리스트를 순회하면서 '<'이 나오는 조건문에서 '>'가 나올 때까지 이터레이터를 돌리기

3. 리스트를 순회하면서 숫자거나 문자열이 나오면 이터레이터가 S의 길이를 초과하지 않는 선에서 해당 구간을 뒤집은 문자열로 교체하기

4. 리스트를 순회하면서 공백이라면 그냥 이터레이터를 돌리기

코드

S = list(input())

i=0
start = 0

while(i < len(S)):
  if(S[i] == '<'):
    i+=1
    while(S[i] != '>'): # 닫는 태그 나올 때까지 i증가 시키면서 돌기
      i+=1
    i+=1 # 닫는 태그후에 i 증가 시킴

  elif(S[i].isalnum()): # 숫자거나 문자열이면
    start = i
    while(i < len(S) and S[i].isalnum()): # 계속 숫자거나 문자열이면 or 모든 문자열을 다 돌았으면
      i+=1
    tmp = S[start:i] # 해당 구간을 거꾸로 돌린 문자열로 교체
    tmp.reverse()
    S[start:i] = tmp

  else: # 공백이라면 i만 증가시킴
    i += 1

print("".join(S))

깨달은 점

1.  out of range 오류를 피하기 위해서 i < len(word) 도 고려하자
  이터러블한 객체를 끝까지 돌 때의 조건을 나는 지금까지 거의 i != len(lst)로만 사용했다.

하지만, 만약 i를 사용해서 리스트의 값을 비교해야 하는 문이 해당 조건문에 같이 들어가게 된다면 IndexError: list index out of range 의 에러가 나올 수밖에 없다.

그럴 때, i < len(word)를 사용하면, out of range 오류가 나지 않으면서 끝까지 순회하도록 할 수 있다는 것을 알아두자.

 

한 가지 더, 위와 같은 상황에선 i < len(word)를 다른 비교문보다 먼저 작성하자. 조건문 안에서 비교문을 먼저 실행함으로써 똑같이 out of range가 발생할 수 있기 때문!

 

2.  순차적으로 순회하는 이터레이터, i 를 잘 활용하자

  문자열의 길이만큼 반복을 해야 하는 건 알았는데 그것을 for문으로만 계속 한정지어서 생각하다 보니 해결방법이 잘 떠오르지 않았다.
하지만 또 다시 생각해 보면, 이 문제는 for문이나 while문이나 별 차이가 없다.
단지, 반복문의 이터레이터를 얼마나 잘 사용했느냐가 관건인 문제가 아닌가 싶다.


이터러블 객체의 끝까지 순차적으로 순회하는 이터레이터인 i를 조건에 따라서 일정 구간 잘 움직이면서 답을 찾아가는 문제인 것이다.
그래도 for문과 while문을 언제 사용하는 것이 적절한지에 대해서도 알아보자.

 

3.  for문과 while문의 차이점!
  for문 : 구하고자 하는 값이 정확한 조건이 있는 경우, 가독성이 좋다.
  while문 : 구하고자 하는 값이 정확한 조건을 정확히 모를 경우 즉, 유동적인 경우, 가독성은 안좋을 수 있다.

'알고리즘 공부 > coding test' 카테고리의 다른 글

백준 10799 [쇠막대기]  (0) 2022.09.16
백준 1931 [회의실 배정]  (0) 2022.05.20
백준 20115 [에너지 드링크]  (0) 2022.05.20
백준 11399 [ATM]  (0) 2022.05.18
백준 2217[로프]  (0) 2022.05.17

문제링크: https://www.acmicpc.net/problem/1931

 

♣ 문제정리

  • 시작시간, 끝나는 시간을 가진 회의들이 있을 때, 회의 수의 최대 개수를 출력하는 문제.
  • 회의가 겹칠 수 없다
  • 회의가 끝나는 동시에 다음 회의가 시작될 수 있다

 

♣ 코드 작성 전 생각할 거리

입력받은 회의들을 시작시간을 기준으로 정렬을 먼저 하기. (회의가 끝났을 때 다음 회의의 시작하는 시간을 바탕으로 계산해야 될 것 같음)

 

첫 회의의 시작시간은 빠를 수록 좋을 줄 알았지만 duration이 길면 이것도 명제가 될 수 없다

(이전 회의 끝나는 시간 <= 다음회의의 시작시간) 의 순서로 하되, 다음 회의의 시작시간이 같은 것들이 여러개라면?

 

start, duration, end 시간을 다 고려를 해야 할 것 같다.

 

===> greedy 기법으로 생각해 본다면, 여러 선택지들이나 두개의 선택지가 있을 때, 어떤 하나를 선택했을 때 빨리 끝나는 회의를 우선적으로 선택하면 되지 않을까?

 

한 가지 더, 끝나는 시간이 같을 경우는? 

빨리 시작하는 회의를 우선적으로 선택해야 한다.

2

2 2

1 2

위 경우 (1 2)를 선택한다면 (2 2)도 선택이 가능해지므로 가능한 회의는 2번으로 결정되지만

(2 2)를 선택한다면 가능한 회의는 1번만으로 결정된다.

 

1. 끝나는 시간을 기준으로 오름차순 정렬

2. 끝나는 시간이 같다면 시작하는 시간이 적은 순으로 오름차순 정렬

 

 

♣ 코드 작성

import sys

input = sys.stdin.readline
n = int(input())

meetings = []
for i in range(n):
    each = list(map(int, input().strip().split(" ")))
    meetings.append(each)

# 끝나는 시간을 기준으로 오름차순 정렬 후 시작시간을 기준으로 오름차순 정렬을 함
meetings = sorted(meetings, key=lambda item: (item[1], item[0])) 

end = meetings[0][1]
cnt = 1

for i in range(1, n):
    if end <= meetings[i][0]: # 다음회의 시작시간이 현재 끝난 시간보다 크거나 같은 것만
        cnt += 1
        end = meetings[i][1]

print(cnt)

전처리를 해주는 과정을 잘 이해하고 코드를 짠다면 뭔가 정말.. 소위 computational thinking으로 쉽게 풀 수 있게 되는 것 같다. 그렇지 않았다면 코드가 복잡해졌을 것 같다.

 

아래 코드는 input() 함수를 사용한 시간이고, 위 코드는 sys.stdin.readline() 을 사용한 시간이다.

 

반복문으로 여러 줄 입력받는 상황에서는 !반드시! 입력은 sys.stdin.readline() 으로 사용해야 겠다!

다만, 한 줄 단위로 입력받기 때문에 개행문자만 제거해주는 strip() 함수만 잘 사용해주자.

'알고리즘 공부 > coding test' 카테고리의 다른 글

백준 10799 [쇠막대기]  (0) 2022.09.16
백준 17413 [단어 뒤집기 2]  (0) 2022.09.16
백준 20115 [에너지 드링크]  (0) 2022.05.20
백준 11399 [ATM]  (0) 2022.05.18
백준 2217[로프]  (0) 2022.05.17

문제링크: https://www.acmicpc.net/problem/20115

 

♣ 문제정리

입력받은 에너지 드링크의 양을 바탕으로 합쳐진 에너지 드링크의 최대양을 구하는 문제

 

♣ 코드 작성 전 생각할 거리

큰 수와 작은 수로 두 수가 주어졌을 때, 최대양을 가지려면 절반의 양을 더해야하는 쪽은 큰 수가 아닌 작은 수가 된다.

더할 양은 최대로 해야하고 반으로 줄여야 하는 것은 가장 적어야 하기 때문이다!

 

결론: 가장 큰 수를 온전히 더하고, 나머지 수는 모두 절반씩 더하면 합쳐진 최대의 에너지 드링크를 출력할 수 있다.

 

♣ 코드 작성

n = int(input())

drink = list(map(int, input().split(' ')))
drink.sort(reverse=True)

sum = drink[0]
for i in range(1, n):
    sum = sum + drink[i]/2

print('%g'%sum)

 

 
 
% (formatting Operator) 앞의 포맷 템플릿에는 대입값 형식이 주어지는데 이를 변환 지시어라고 부른다.
 
-> 포맷을 가진 문자열을 만들어주는 연산자
출처: http://pythonstudy.xyz/python/article/9-%EB%AC%B8%EC%9E%90%EC%97%B4%EA%B3%BC-%EB%B0%94%EC%9D%B4%ED%8A%B8

 

5

3 2 10 9 6

위 테스트 케이스에서 출력값이 20이 나와야 하는데 포맷팅을 안해주면 20.0이 나오기 때문에 '%g'%sum 을 사용.

 

출처: 공식문서, https://docs.python.org/ko/3/library/string.html

%g 는 유효하지 않은 후행 0은 모두 유효숫자부에서 제거되는 특성이 있다. 716.5 와 같이 유효한 후행만 남겨둘 수 있다!! 

 

 

참고: https://coding-nyan.tistory.com/75

 

 

'알고리즘 공부 > coding test' 카테고리의 다른 글

백준 17413 [단어 뒤집기 2]  (0) 2022.09.16
백준 1931 [회의실 배정]  (0) 2022.05.20
백준 11399 [ATM]  (0) 2022.05.18
백준 2217[로프]  (0) 2022.05.17
백준 2358 [평행선]  (0) 2022.02.08

문제링크: https://www.acmicpc.net/problem/11399

 

♣ 문제정리

사람의 수 N

i번째 사람이 돈을 인출하는 데 걸리는 시간 : 입력값 (1,2,3...N)

순서를 아무렇게나 할 수 있음

각 사람이 돈을 인출하는 데 걸리는 총 시간의 최소값: 출력값

 

 

♣ 코드 작성 전 생각할 거리

경우의 수: N!

총 시간이 최소인 경우의 순서를 알 필요는 없다.

가장 오래 걸리는 사람을 조금 더하고, 가장 적게 걸리는 사람을 가장 많이 더해야지 총 합이 최소

-> 정렬!

 

 

 

♣ 코드 작성

총 시간을 구하려면 배열에서 각 원소에 왔을 때 처음부터 그 순서까지를 계속 더해야 한다

i:0 -> 0

i:1 -> 0, 1

i:2 -> 0,1,2

i:3 -> 0,1,2,3

i:4 -> 0,1,2,3,4

 

이것에 충실하게 코드를 작성했다

n = int(input())

# fetch하는 time 넣을 리스트
f_times = list(map(int, input().split(' ')))

f_times.sort()

sum = 0
k=1

while(k <= n):
    for i in range(0, k):
        sum = sum + f_times[i]
    k += 1

print(sum)

 

 

하지만, 조금만 더 생각해 보면,

sum이나 k라는 변수를 따로 만들지 않아도 배열을 순차적으로 갱신해주는 방법도 있다!

우리가 구해야 하는 것은 소요시간들의 합이기 때문에 각 배열의 원소들을 이전 원소들을 더한 합으로 바꿔준다. 

=> 순차적으로 각 원소는 (자신의 값 + 이전 원소값)으로 바꿔준다.

그리고 바뀐 배열들의 합을 구해도 같은 답이 나오게 된다.

for i in range(1, n):
    f_times[i] += f_times[i-1]
print(sum(f_times))

코드길이도 많이 줄었고 시간은 거의 절반으로 줄어듬을 알수 있다!!!!!!

memoization을 사용한 방법

동일한 계산을 반복해야 할 때, 이전에 계산한 값을 메모리에 저장함으로써 동일한 계산의 반복 수행을 제거하여 프로그램 실행 속도를 빠르게 하는 기술! 동적 계획법의 핵심

 

 

코드를 작성하러 들어가기 전에 어떻게 작성할 건지를 확실하게 하는 게 시간을 절약하는 데 중요하다!

즉, 코드 작성보다는 문제를 분석하는 데에 시간을 더 투자하자

'알고리즘 공부 > coding test' 카테고리의 다른 글

백준 1931 [회의실 배정]  (0) 2022.05.20
백준 20115 [에너지 드링크]  (0) 2022.05.20
백준 2217[로프]  (0) 2022.05.17
백준 2358 [평행선]  (0) 2022.02.08
백준 2609 [최대공약수와 최소공배수]  (0) 2021.02.04

문제링크 : https://www.acmicpc.net/problem/2217

 

♣ 문제정리

k 개의 로프를 병렬로 연결

각 로프에는 모두 고르개 w/k 만큼의 중량이 걸린다

로프를 이용하여 들어올릴 수 있는 물체의 최대 중량(w)을 구하라

모든 로프를 사용할 필요는 없다 => 사용하는 로프가 1개, 2개, 3개 ,,,, k개

 

입력: 각 로프가 버틸 수 있는 최대 중량

출력: 로프를 이용하여 들어올릴 수 있는 물체의 최대 중량

 

♣ 코드 작성 전 생각할 거리

만약 모든 로프를 사용한다면 물체의 최대 중량은 

=> (로프가 버틸 수 있는 최대 중량 중 가장 최소 값) * k개 일 것이다.

 

하지만, 

모든 로프를 사용할 필요는 없기 때문에 케이스마다 사용하는 로프의 개수를 1개, 2개, 3개 ,,,, k개로 나눈다면,

(로프의 개수) * (해당하는 로프들 중 가장 최소 값) 으로 계산해서 가장 최대인 값이 출력돼야 한다!

 

그러려면  입력되는 로프들을 정렬을 해야한다. 최대중량이 제일 큰 로프 순으로 꺼내면서 순서대로 병렬을 해야 하기 때문이다.

 

♣ 코드 작성

k = int(input())

ropes = []
for i in range(k):
    ropes.append(int(input()))

ropes.sort(reverse=True) # 내림차순 정렬

weights = []
for i in range(k):
    w = (i+1) * ropes[i]
    weights.append(w)

print(max(weights))

참고: https://pangsblog.tistory.com/21

https://jitolit.tistory.com/134

'알고리즘 공부 > coding test' 카테고리의 다른 글

백준 20115 [에너지 드링크]  (0) 2022.05.20
백준 11399 [ATM]  (0) 2022.05.18
백준 2358 [평행선]  (0) 2022.02.08
백준 2609 [최대공약수와 최소공배수]  (0) 2021.02.04
백준 11022 [A+B-8]  (0) 2021.02.04

https://github.com/tony9402/baekjoon

 

GitHub - tony9402/baekjoon: 코딩테스트 대비 문제집(Baekjoon Online Judge)

코딩테스트 대비 문제집(Baekjoon Online Judge). Contribute to tony9402/baekjoon development by creating an account on GitHub.

github.com

https://github.com/VSFe/Algorithm_Study

 

GitHub - VSFe/Algorithm_Study: This repository consists of materials for those preparing for coding tests and algorithm intervie

This repository consists of materials for those preparing for coding tests and algorithm interviews. - GitHub - VSFe/Algorithm_Study: This repository consists of materials for those preparing for c...

github.com

 

'알고리즘 공부 > 파이썬 개념' 카테고리의 다른 글

코드업 6097번 문제  (0) 2022.01.26
코드업 100제 [파이썬] 51-100제  (0) 2022.01.24
코드업 100제 [파이썬] 1-50제  (0) 2022.01.23

https://www.acmicpc.net/problem/2358

 

2358번: 평행선

첫째 줄에 n(1 ≤ n ≤ 100,000)이 주어진다. 다음 n개의 줄에는 각 점의 좌표가 주어진다. 만약 입력에 서로 같은 두 점이 주어지면, 그 두 점을 이용하여 직선을 만들 수 있다. 좌표는 절댓값이 231보

www.acmicpc.net

원리.

x축에 평행하다 -> y좌표가 같다

y축에 평행하다 -> x좌표가 같다

 

 만약 입력에 서로 같은 두 점이 주어지면, 그 두 점을 이용하여 직선을 만들 수 있다.

(1, 0) 하나로도 직선을 만들 수 있고, (2, 0) 하나로도 직선을 만들 수 있고, (3, 0) 하나로도 직선을 만들 수 있다는 뜻이다.

하지만,

(1, 0) (2, 0) (3, 0)은 세개 다 y축에 평행하지만 같은 축으로 인식해야 한다.

즉, y = 0인 축 하나라고 인식해야 한다.

 

import sys

n = int(sys.stdin.readline())

dots = []
for _ in range(n):
  dot = tuple(map(int, sys.stdin.readline().split(' ')))
  dots.append(dot)

Xs = []
Ys = []
count = 0
for i in range(n):
  for k in range(i+1, n):
    if(dots[i][0] == dots[k][0]): #x좌표 같은지 확인 (y축에 평행)
      if not dots[i][0] in Xs: #같다면 중복되지 않도록
        Xs.append(dots[i][0])
        count += 1
      else:
        continue
    if(dots[i][1] == dots[k][1]): #y좌표 같은지 확인 (x축에 평행) 
      if not dots[i][1] in Ys: #같다면 중복되지 않도록
        Ys.append(dots[i][1])
        count += 1
      else:
        continue
    else:
      continue
print(Xs)
print(Ys)
print(count)

리스트 안에 튜플을 넣도록 해서 각 좌표마다 for문을 돌면서 같은 게 있는지 체크했다.

x좌표에서 같은 게 있다면 x좌표의 리스트(=Xs)에 보관해서 같은 축이라면 중복돼서 count되지 않도록 했다.

똑같이, y좌표에서 같은 게 있다면 y좌표의 리스트(=Ys)에 보관해서 같은 축이라면 중복돼서 count되지 않도록 했다.

 

이렇게 구현하니까 동작은 잘 되는 듯 했지만 시간 초과 오류가 난다....

 


 

그래서 딕셔너리, 집합, 튜플 등 여러 데이터타입으로 해봤지만 딕셔너리는 같은 key 값이면 value값을 이전 값을 지우고 새로운 값만을 덮어서 저장하고 집합은 중복해서 저장하지 않기 때문에 같은 축이었을 경우를 구분짓지 못했다... 그래서 이상하고 요상한 방법으로 시도해봤지만 다시 시간 초과 오류가 떴다.

 

그러다가 다른 블로그 글을 봤는데, 몰랐던 데이터타입을 발견할 수 있었다. 

defaultDict() 라는 유사딕셔너리 이다.

딕셔너리는 조작할 때 value값을 계속 바꾸게 된다.

defaultdict 생성

하지만 디폴트 딕셔너리의 경우에 value 값을 리스트나 정수, 집합으로 디폴트를 바꿀 수 있고,

리스트라면 리스트의 함수를 사용할 수 있게 한다.

이렇게 리스트의 함수인 append를 사용해서 넣으면 내가 원했던 것처럼 value가 여러개면 여러개가 하나의 key값에 다 들어가게 되는 걸 볼 수 있었다.

 

 

그런데 이렇게 값을 넣어버리면 할당으로 값이 변하게 되는 것이기 때문에 

이전의 값에 덮어씌워지는 문제가 발생한다.

 

 

 

collections로부터 defaultdict함수를 가져와서 defaultdict(list)로 생성을 하고,

리스트 함수에 하듯이 append()함수를 붙여서 추가해주면 key값이 같더라도 value가 덮어씌워지는 것이 아니라 리스트 형태로 차곡차곡 쌓일 수 있게 된다.!

그럼 이것을 활용해서 

 

x좌표를 key로 하고 y좌표를 value로 한 딕셔너리,

y좌표를 key로 하고 x좌표를 value로 한 딕셔너리

두개의 딕셔너리를 만든다.

그리고 각 key 값에 대해서 value값이 2개 이상이면 count 값을 증가시켜준다.

from collections import defaultdict
import sys

n = int(sys.stdin.readline())

#유사딕셔너리 사용 : dict 클래스의 서브 클래스
#딕셔너리의 value의 디폴트를 리스트로 생성함
xDots = defaultdict(list) #x가 key, y가 value 
yDots = defaultdict(list) #y가 key, x가 value

for i in range(n):
  x, y  = map(int, input().split(' '))
  xDots[x].append(y) #리스트 함수를 사용할 수 있게 됨
  yDots[y].append(x)

count = 0
for i in xDots.keys(): # y축 평행 => y값 같은 게 있다
  if(len(xDots[i]) >= 2): #하나의 key 값에 2개 이상의 value값이 있다면 증가시킴
    count+= 1

for i in yDots.keys():  # x축 평행 => y값 같은 게 있다
  if(len(yDots[i]) >= 2):
    count+= 1
print(xDots, yDots)
print(count)

 

참고: https://firsteast.tistory.com/126

 

'알고리즘 공부 > coding test' 카테고리의 다른 글

백준 11399 [ATM]  (0) 2022.05.18
백준 2217[로프]  (0) 2022.05.17
백준 2609 [최대공약수와 최소공배수]  (0) 2021.02.04
백준 11022 [A+B-8]  (0) 2021.02.04
백준 2747 [피보나치수]  (0) 2021.01.22
TypeError: 'int' object is not subscriptable
h,w = map(int,input().split()) #5 5
n = int(input()) #3

d=[]
for i in range(h):
    d.append([])
    for k in range(w):
        d[i].append(0) 

for count in range(n):
    l, d, x, y = map(int, input().split())
    x=x-1
    y=y-1 #0 1 2 3 4 범위로 바꿈
    
    for j in range(l):
        if(d == 0):
            d[x][y+j] = 1   
        else:
            d[x+j][y] = 1
            

for i in range(h):
    for k in range(w):
        print(d[i][k], end=' ')
    print()

분명 맞게 짠 코드 같은데 자꾸 에러가 나서 뭘까 고민했는데 

오류내용은 인덱스를 갖지 않는 값에 인덱스를 가지게 코드를 짤 경우 발생하는 오류였다.

변수 d도 선언하고 리스트 이름도 d로 선언했기 때문에 충돌이 나서 그랬던 것 같다..!

 

리스트명을 board로 바꿔줬더니 잘 작동이 됐다!

앞으로는 에러가 난다면 변수명도 꼼꼼히 보는 습관을 들이자

h,w = map(int,input().split()) #5 5
n = int(input()) #3

board=[]
for i in range(h):
    board.append([])
    for k in range(w):
        board[i].append(0) 

for count in range(n):
    l, d, x, y = map(int, input().split())
    x=x-1
    y=y-1 #0 1 2 3 4 범위로 바꿈
    
    for j in range(l):
        if(d == 0):
            board[x][y+j] = 1   
        else:
            board[x+j][y] = 1
            

for i in range(h):
    for k in range(w):
        print(board[i][k], end=' ')
    print()

 

a = bool(int(input())) -> input( ), int( ), bool( ) 순서로 한 번에 한 단계씩 계산/처리/평가된다.

참 또는 거짓의 논리값을 역(반대)으로 바꾸기 위해서 not 예약어(reserved word, keyword)를 사용할 수 있다.

정수값 0은 False 이고, 나머지 정수 값들은 True 로 평가된다.

 

** 비트단위(bitwise)연산자는,
~(bitwise not), &(bitwise and), |(bitwise or), ^(bitwise xor),
<<(bitwise left shift), >>(bitwise right shift)
가 있다.

 

2의 보수 방법을 코드로 쉽게 구현할 수 있다!

~n = -n - 1
-n = ~n + 1 과 같은 관계로 표현할 수 있다.

a = 1
print(~a) #-2가 출력된다.

 

3개의 요소로 이루어지는 3항 연산은 아래와 같은 형태다.
=> C는 조건식, C가 참일 경우 x, 거짓일 경우 y

x if C else y

 

print('%X'%n)    #n에 저장되어있는 값을 16진수(hexadecimal) 형태로 출력

 

파이썬은 가독성을 중시하는 언어이므로 증감연산자 ( ++, -- )는 사용할 수 없다!

=> 그대신 i += 1 또는 i -= 1이 사용될 수 있다!

 

글자들을 이어붙이기 (sep)

print('p', 'y', 't', 'h', 'o', 'n', sep='')
python

 

print문 이어붙이기 (end)

print("안녕", end='/')
print("하세", end='/')
print("요", end='/')
안녕/하세/요

 

'알고리즘 공부 > 파이썬 개념' 카테고리의 다른 글

공부하기 유용한 사이트!  (0) 2022.02.17
코드업 6097번 문제  (0) 2022.01.26
코드업 100제 [파이썬] 1-50제  (0) 2022.01.23

+ Recent posts