728x90
문제

상근이는 겨울방학을 맞아 N개국을 여행하면서 자아를 찾기로 마음먹었다.

하지만 상근이는 새로운 비행기를 무서워하기 때문에, 최대한 적은 종류의 비행기를 타고 국가들을 이동하려고 한다.

이번 방학 동안의 비행 스케줄이 주어졌을 때, 상근이가 가장 적은 종류의 비행기를 타고 모든 국가들을 여행할 수 있도록 도와주자.

상근이가 한 국가에서 다른 국가로 이동할 때 다른 국가를 거쳐 가도(심지어 이미 방문한 국가라도) 된다.

 

입력

첫 번째 줄에는 테스트 케이스의 수 T(T ≤ 100)가 주어지고,

각 테스트 케이스마다 다음과 같은 정보가 주어진다.

  • 첫 번째 줄에는 국가의 수 N(2 ≤ N ≤ 1 000)과 비행기의 종류 M(1 ≤ M ≤ 10 000) 가 주어진다.
  • 이후 M개의 줄에 a와 b 쌍들이 입력된다. a와 b를 왕복하는 비행기가 있다는 것을 의미한다. (1 ≤ a, b ≤ n; a ≠ b) 
  • 주어지는 비행 스케줄은 항상 연결 그래프를 이룬다.
출력

테스트 케이스마다 한 줄을 출력한다.

  • 상근이가 모든 국가를 여행하기 위해 타야 하는 비행기 종류의 최소 개수를 출력한다.
예제 입력
2
3 3
1 2
2 3
1 3
5 4
2 1
2 3
4 3
4 5
예제 출력
2
4
코드 및 설명
import sys
input=sys.stdin.readline

t=int(input())

for i in range(t):
    n,m=map(int,input().split())
    for j in range(m):
        input()
    print(n-1)

트리 문제이지만 어떤 특징을 가지는지 이해하고 풀게 되면 가장 쉬운 문제라고 할 수 있을 것 같다.

처음에 이 문제를 보았을 때 어떻게 풀어야 하는지 감이 안왔는데 이해하고 나니 코드가 바로 짜질 정도였다.

 

이 문제에서 주목해야 할 것이 연결 그래프라는 사실이다.

그래프 문제이기도 한데 연결그래프는 모든 모드가 연결되어 있다는 것을 의미한다.

 

여기서 최소로 비행기를 타고 이동한다는 의미는 국가를 한번씩 거쳐가면 된다는 의미로 해석하면 된다.

왕복 하고, 중복으로도 갈 수 있지만 결국 이 문제에서 원하는 것은 최소의 경우다.

 

그렇기에 연결리스트에서 각 Node 연결 정보가 주어지더라도 결과값에 사용하지 않아도 된다는 것이다.

그래서 input()으로만 받고 따로 저장하지 않았다.

 

그리고 n,m으로 입력 받은 것 중에 방문할 나라의 수보다 한번만 적으면 Edge의 개수(방문한 경로)가 되므로 이를 이용해 출력해주었다.

728x90

'Python > Baekjoon' 카테고리의 다른 글

[Python] 백준 1065 트리  (0) 2022.09.15
[Python] 백준 10815 숫자카드  (0) 2022.09.06
[Python] 백준 13305 주유소  (0) 2022.09.03
[Python] 백준 10828 스택  (0) 2022.07.29
[Python] 백준 1920 수찾기  (0) 2022.07.07
728x90

지난 포스팅에서는 개발방향에 대해서 소개를 하였다.

이번 포스팅에서는 바뀐 개발방향에 따라 어떤 기능을 개발하고 있는지 소개하려고 한다.

https://github.com/yujin37/Auto_Trading

 

GitHub - yujin37/Auto_Trading: CodeCure 주식자동매매기 개발 (22.3~ ing)

CodeCure 주식자동매매기 개발 (22.3~ ing). Contribute to yujin37/Auto_Trading development by creating an account on GitHub.

github.com

 

pyqt designer을 통한 GUI 배치

 

이전에는 코드 상에서 하나하나 위치를 직접 배치했다. GUI를 따로 작업안하고 코드 상에서 바로 할 수 있다는 점은 좋았지만 배치하는데에 어려움이 있었다. 실행해서 직접 위치를 확인했다. 이건 시간이 많이 걸리는 작업이었다.

 

그래서 이번에는 자료를 보면서 따라갔다.

https://wikidocs.net/5858

 

3) PyTrader 구현

이번 절에서는 그림 18.1의 PyTrader 프로그램을 만들어 보겠습니다. 가장 먼저 할 일은 Qt Designer를 이용해 메인 윈도우를 만드는 것입니다. 아직은 윈도우 ...

wikidocs.net

이 내용이 pytrader.py 작업하기 위한 ui를 만드는 내용이다.

처음에는 배치하고 방식을 이해하는데에 시간이 좀 걸렸다. 그렇지만 한번 만들고나니 버튼을 추가하고 그룹을 묶는 등의 작업등이 매우 쉬워졌다. anaconda에서 designer라고 입력하면 ui를 작업 할 수 있는 pyqt designer가 열리게 된다.

작업하고 나서 저장하면 pytrader에서 연결된 ui 파일에 따라 프로그램 실행 시 바로 보인다.

 

매수, 매도, 잔고조회

 

이 부분은 그대로 책의 내용을 따라갔다. 

https://wikidocs.net/5858

 

3) PyTrader 구현

이번 절에서는 그림 18.1의 PyTrader 프로그램을 만들어 보겠습니다. 가장 먼저 할 일은 Qt Designer를 이용해 메인 윈도우를 만드는 것입니다. 아직은 윈도우 ...

wikidocs.net

앞에 링크한 것과 같은데 여기에 일차별로 다 따라가서 만들었다.

매수 알고리즘이랑 매수, 매도 주문 넣는 것을 참고하였다.

 

자동 매도 알고리즘

 

이 부분은 순수하게 직접 개발했다.

위 위키독스 책에는 급등주 매수밖에 내용이 없었기 때문이다. 

매도는 사실 급등주보다는 수익률에 기반한 것이 대부분이다. 그렇기 때문에 수익을 일정 비율 이상 얻게 되면 팔도록 하는 것이 맞다는 생각이 들었다. 그리고 이 수익률을 어떻게 가져올지 생각을 하였다. 새로운 함수를 만들어서 하는 방법도 있긴 하지만 이건 아직 능력이 부족하기도 하고 에러도 많이 났다.

가장 현실적인 방법은 잔고조회의 종목별 수익 코드 활용이었다. 여기에 기존에는 종목코드가 없었는데 코드를 수정해 종목코드를 가져오게 했다. 그리고 여기에 있는 수익률을 가져왔다. 그래서 일정 비율이상 넘어가면 매도 리스트 파일에 추가하도록 하는 리스트로 담아주었다. 이건 각 종목에 대해 따로 진행할 수 없다는 것이 단점이지만 기본적인 수익 매도는 가능하지 않을까 싶다.

 

자동 매수, 매도 시 진행 함수 수정

 

기존에 자료에서는 단 한번만 매수, 매도를 진행했다. 이것의 치명적인 문제였다. 계속 진행해야 하는데 한번하면 끝나버리니 이걸 수정해주어야 했다. 방법은 trade_stocks_done을 True로 설정해 잠근 후에 주문하고, 파일 내용을 바꾼 후 다시 초기 상태, trade_stocks_done을 False를 해주어야 한다. 그러면 계속 함수가 실행될 수 있게 된다.

 

 

이렇게 현재는 기능들을 구현하고 있다. 이후에 진행할 기능들은 체결, 미체결 현황 조회, 주문과 관련해서 속도를 빠르게 하기위한 작업, 차트조회이다. 이 부분도 차례대로 구현할 예정이다.

 

다음 포스팅에서는 키움api와 관련해 스레드, 멀티프로세싱 관련 이야기를 하도록 하겠다.

728x90
728x90

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

 

1068번: 트리

첫째 줄에 트리의 노드의 개수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에는 0번 노드부터 N-1번 노드까지, 각 노드의 부모가 주어진다. 만약 부모가 없다면 (루트) -1이 주어진다

www.acmicpc.net

문제

트리에서 리프 노드란, 자식의 개수가 0인 노드를 말한다.

트리가 주어졌을 때, 노드 하나를 지울 것이다. 그 때, 남은 트리에서 리프 노드의 개수를 구하는 프로그램을 작성하시오. 노드를 지우면 그 노드와 노드의 모든 자손이 트리에서 제거된다.

예를 들어, 다음과 같은 트리가 있다고 하자.

현재 리프 노드의 개수는 3개이다. (초록색 색칠된 노드) 이때, 1번을 지우면, 다음과 같이 변한다. 검정색으로 색칠된 노드가 트리에서 제거된 노드이다.

이제 리프 노드의 개수는 1개이다.

 

입력

첫째 줄에 트리의 노드의 개수 N이 주어진다. N은 50보다 작거나 같은 자연수이다. 둘째 줄에는 0번 노드부터 N-1번 노드까지, 각 노드의 부모가 주어진다. 만약 부모가 없다면 (루트) -1이 주어진다. 셋째 줄에는 지울 노드의 번호가 주어진다.

 

출력

첫째 줄에 입력으로 주어진 트리에서 입력으로 주어진 노드를 지웠을 때, 리프 노드의 개수를 출력한다.

 

예제 입력 1 
5
-1 0 0 1 1
2
예제 출력 1
2
코드 및 설명
import sys
input=sys.stdin.readline

n=int(input())

result=[[] for _ in range(n)]
node=list(map(int,input().split()))

x=int(input())
for i in range(n):
    result[i]=node[i]

def delete(x):
    result[x]=-2
    for i in range(n):
        if result[i]==x:
            result[i]=-2
            delete(i)

delete(x)
cnt=0

for i in range(n):
    if result[i]!=-2:
        err=0
        for j in result:
            if j==i:
                err=1
        if err==0:
            cnt +=1
print(cnt)

이 문제는 트리 관련 연습 문제를 찾다가 발견하게 된 문제

트리에 대한 개념 이해도 부족했겠지만 골드 단계이기에 좀 더 어렵게 느껴졌다.

 

코드에 대해서 설명해보겠다.

일단 입력 과정에서 짚어야 할 것은 리스트 내에서 반복문을 통한 2중 리스트 만들기

이걸 처음에 방법을 잘 몰라서 []*n 이런 방식으로 했는데 이런 경우에는 빈 리스트가 생성되지 않았다.

그래서 이렇게 [[] for _ in range(n)]방식으로 생성을 시켜주어야 한다.

노드와 리프 노드 찾는 입력 생성은 어렵지 않으니 넘어가도록 하겠다.

 

그리고 앞에서 생성한 리스트에 입력받은 리스트를 넣어주었다.

 

함수를 한번 살펴보자면

리프 노드를 찾는 위치는 -2로 설정해서 다른 숫자와 겹쳐지지 않게 한다.

그리고 모든 result의 요소를 탐색해 찾고자 하는 위치라면 노드가 연결되어 있으므로 -2로 값을 바꿔주고 다시 그 위치에 대해 호출해준다.

 

그리고 출력을 위한 작업을살펴보도록 하자

일단 -2가 아니라면 진입하도록 하는데, 기본 세팅을 0으로 하고 result의 값을 비교한다.

만약 result의 요소와 같은 숫자가 i에서 나오게 되면 리프노드가 삭제된 사건이므로 err를 1로 해준다.

err가 0으로 그대로라면 리프노드이므로 갯수를 카운트 해준다.

그리고 이 결과값을 최종적으로 출력해주면 된다.

 

트리에 대해 어떻게 구성해야 하는지 생각하게 해주는 문제였다.

728x90

'Python > Baekjoon' 카테고리의 다른 글

[Python] 백준 9372 상근이의 여행  (1) 2022.10.08
[Python] 백준 10815 숫자카드  (0) 2022.09.06
[Python] 백준 13305 주유소  (0) 2022.09.03
[Python] 백준 10828 스택  (0) 2022.07.29
[Python] 백준 1920 수찾기  (0) 2022.07.07

+ Recent posts