파이썬 알고리즘 : Moo게임, 문자열폭탄, 스카이라인

2023년 7월 30일 알고리즘 문제풀이 백준 5904번 문제 링크 1차 시도 나의 생각 재귀 함수를 통해 각 문자열을 구할 수 있었다. 또한 그 문자열의 길이도 규칙적이므로 몇번째 재귀에서 n번째 문자열이 등장하는지를 알아내어 그 문자열의 index를 통해 구하였다. 하지만 메모리 초과와 시간 초과로 인하여 오답처리 되었다. 결과 오답 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 import sys sys.setrecursionlimit(10**6) n = int(sys.stdin.readline()) def moo(k): if k == 0: return 'moo' return moo(k-1)+'m'+'o'*(k+2)+moo(k-1) i = -1 while True: i += 1 tmp = moo(i) if len(tmp) >= n: print(tmp[n-1]) break 2차 시도 나의 생각 문자열을 구하면 안된다고 생각하였다. 다음 문자열이 이전 차례의 문자열 두개에 하나의 규칙적인 문자가 껴있는 형태라는 사실에 집중하였다. 예를 들어 S(10)의 몇번째 문자열인지는 S(9)의 문자열을 통해 알 수 있다. 원리는 다음과 같다. ...

2023년 7월 30일 · 8 분 · 배준수

파이썬 알고리즘 : 철로, 카드 정렬하기

2023년 7월 29일 알고리즘 문제풀이 백준 13334번 문제 링크 1차 시도 나의 생각 사람들의 사무실 과 집 둘 중 좌표가 작은 것을 먼저 오게 한 후, 그것을 오름차순으로 배열에 정리하였다. 각 지점을 철로의 시작점으로 삼아 모든 case를 검사하며 최댓값을 업데이트했다. 다 검사해버리니 당연히 시간초과… 결과 오답 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 import sys from heapq import heappop, heappush n = int(sys.stdin.readline()) people = [] for _ in range(n): h,o = map(int,sys.stdin.readline().split()) if h <= o: heappush(people,[h,o]) else: heappush(people,[o,h]) d = int(sys.stdin.readline()) ans = 0 while people: cnt = 0 x = people[0][0] for person in people: if person[0] >= x and person[1] <= x+d: cnt += 1 ans = max(ans,cnt) heappop(people) print(ans) 2차 시도 나의 생각 어떤 사람의 집과 사무실의 거리는 철로의 길이인 d보다 멀 수도있다. 이 사람은 철로를 어디에 설정하든 이용할 수 없다. 따라서 입력을 받을 때 이런 케이스를 지우려고 했다. 또한 정렬을 해버린 만큼 굳이 필요하지 않은 조건들도 제거하였다. 하지만 예외케이스가 있는지 오답처리되었다. ...

2023년 7월 29일 · 5 분 · 배준수

파이썬 알고리즘 : 가운데를 말해요

2023년 7월 28일 알고리즘 문제풀이 백준 1655번 문제 링크 1차 시도 나의 생각 양 끝과 중간이라는 생각에 deque을 사용하면 어떨까 생각하고 코드를 작성했다. 생각해보니 중간과 끝 사이에 새로운 숫자를 집어넣어야 하는데… 다행히 우선순위 큐, 최소 heap이 생각났지만 너무 늦게 생각나서 코드 작성을 못했다. 다음 시도에선 해봐야지. 결과 오답 코드 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import sys from heapq import heappop, heappush, heappushpop n = int(sys.stdin.readline()) big = [] mid = [] small = [] for _ in range(n): num = int(sys.stdin.readline()) if not mid: mid.append(num) print(num) continue if num >= mid: tmp = heappushpop(big,num) mid.append(tmp) print(mid[0]) else: tmp = heappushpop(small,-num) mid.append(-tmp) mid.sort() print(mid[0]) 2차 시도 나의 생각 heap을 사용하였다. 가운데 값을 기준으로 크냐 작냐에 따라 경우가 나눠질거라고 생각해서 가운뎃값보다 작은 heap, 가운뎃값을 담은 heap, 더 큰 heap 세개로 나누어서 생각했다. 하지만 문제에서 나왔듯 가운데 값이 전체 숫자의 갯수에 따라 2개일 수도 한 개 일수도 있어서 가운데를 담는 배열을 1로 유지해야할지, 혹은 큰 배열과 작은 배열의 수를 갖게 유지해야할 지 여러모로 헷갈렸다. 차라리 하나를 우직하게 했으면 정답은 나왔으려나.. 여러 생각에 헤메다가 시간만 허비하고 코드를 완성하지 못했다. ...

2023년 7월 28일 · 5 분 · 배준수

파이썬 알고리즘 : 요세푸스 문제 0, 뱀, 최대 힙

2023년 7월 28일 알고리즘 문제풀 백준 11866번 문제 링크 1차 시도 나의 생각 처음엔 인덱스를 옮겨가면서 없어진 수를 표시하는 방법을 생각했다. 예를 들어 [[1,0].[2,0],[3,0],[4,0].[5,0]] 이런 식을 설정하고 빠지는 원소는 2번째 원소를 1로 바꿔주는 방법. 하지만 굳이 배열을 한번 더 복잡하게 만들어야 할 필요성이 없다고 생각했다. 따라서 덱으로 설정한 배열의 가장 앞 원소만 주목하되, 현재 뺄 차례인지 그냥 넘어갈 차례인지만 분류하면 되겠다고 판단하였다. 뺄 차례라면 popleft 한 후 따로 만들어둔 정답을 위한 배열에 append 하였다. 로직 자체는 어려움이 없었으나 예제에서 출력할 때 수열을 담는 괄호가 대괄호가 아니라 그냥 괄호 ‘<>‘였다. 이 부분이 신경쓰였지만 가장 먼저 ‘<‘를 배열의 앞에 넣어주고, 수열을 넣을 때 마다 숫자를 str로 바꾼 후 따옴표(,)와 공백( )을 붙여서 넣었다. 그 이후 *를 이용해 원소들만 출력했다. ...

2023년 7월 27일 · 5 분 · 배준수

파이썬 알고리즘 : 원 영역, 히스토그램에서 가장 큰 직사각형

2023년 7월 26일 알고리즘 문제 풀이 백준 6549 문제 링크 시도1 나의 생각 왼쪽부터 반복문을 통해 조건에 따라 스택에 사각형의 넓이를 넣고 수정하는 방법을 사용하였다. 스택에는 사각형의 높이와 너비가 원소인 배열을 집어넣었다. 예를 들어, 이번 사각형의 높이가 4라면 [4,1]을 넣어주는 방법이다. 맨 처음을 위해 스택이 비어있을 땐 조건과 무관하게 스택에 삽입하였다. 이후는 최근 스택에 들어간 사각형의 높이(이전 사각형)와 현재 반복문에서 주목하는 사각형(현재 사각형)의 높이를 비교하였다. 만약 현재 사각형의 높이가 더 크거나 같다면, 스택에 들어 있는 사각형은 너비를 1 늘렸다. 이후는 현재 사각형과 더 이전에 들어갔던 사각형들의 높이를 비교하였다. 그래서 너비를 1 늘려주거나 만약 현재 사각형의 높이가 작으면 너비를 늘리지 않고 스택에 들어 있는 사각형의 높이와 너비를 곱하여 넓이를 구한 후 최댓값과 비교하여 저장하는 방법을 사용하였다. 로직을 정리해보자면 다음과 같다. 문제에서는 각 케이스별로 출력해야 하지만, 편의를 위해 하나의 케이스에서 발생하는 로직만 표시하였다. ...

2023년 7월 26일 · 10 분 · 배준수

3. 함수의 증가(2)

3.2 표준 표기법과 흔히 사용되는 함수 단조성 m≤n일 때 f(m)≤f(n)이면 함수 f(n)은 단조증가 m≤n일 때 f(n)≤f(m)이면 함수 f(n)은 단조감수 m<n일 때 f(m)<f(n)이면 함수 f(n)은 순증가 m<n일 때 f(n)<f(m)이면 함수 f(n)은 순감소 내림과 올림 x의 내림 : 임의의 실수 x에 대해 x 이하의 정수 중 가장 큰 수 x의 올림 : 임의의 실수 x 에 대해 x 이하의 정수 중 가장 작은 수 a mon n = a%n = a를 n으로 나눈 나머지(remainder, residue) ...

2023년 7월 23일 · 1 분 · 배준수

3. 함수의 증가(1)

3. Growhth of Functions 일반적으로 알고리즘의 정확한 실행 시간을 계산할 필요가 없다. 입력이 충분히 크면 최고차항간 비교만 유의미하기 때문이다. ex) 병합정렬(nlgn), 삽입정렬(n^2) 처럼 이전에 공부한 애들을 보면 알 수 있음. 입력이 충분히 커서 실행 시간의 증가율의 상대적 순서만 볼때, 우리는 알고리즘의 점근적(asymptotic) 효율성을 따지게 된다. 입력 크기가 아주 작을 때를 제외하고는 일반적으로 최선의 선택이 될 수 있다. 즉, 일반적인 상황이란 최고차항의 차수로 실행시간의 차이를 비교하는 때를 말하는데 이 때는 점근적으로 접근하게 된다. ...

2023년 7월 19일 · 6 분 · 배준수

11.5 웹 서버

11.5 웹서버 11.5.1 웹 기초 Clients 와 servers 는 HyperText Transfer Protocol(HTTP)를 사용하여 의사소통한다. Client와 server는 TCP 연결을 설립한다. client는 컨텐츠(content)을 요구한다(request) server는 요청된 컨텐츠에 응답한다(respond). client와 서버는 연결을 끊는다(결국 언젠가는) 11.5.2 Web content 웹 서버는 **컨텐츠(content)**를 client에게 반환한다. content : 연관된 MIME(Multipurpose Internet Mail Extension) 타입을 갖는 바이트 배열 ex. MIME 타입의 예시 text/html HTML document text/plain Unformatted text image/gif Binary image encoded in GIF format image/png Binary image encoded in PNG format image/jpeg Binary image encoded in JPEG format Static and Dynamic content HTTP 응답에서 반환된 컨텐츠는 **정적(static)**일수도 **동적(dynamic)**일수도 있다. ...

2023년 4월 16일 · 8 분 · 배준수

TINY Web Server

11.6 종합 설계: 소형 웹 서버 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 /* * tiny.c - A simple, iterative HTTP/1.0 Web server that uses the * GET method to serve static and dynamic content */ #include "csapp.h" void doit(int fd); void read_requesthdrs(rio_t *rp); int parse_uri(char *uri, char *filename, char *cgiargs); void serve_sattic(int fd, char *filename, char *cgiargs); void get_filetype(char *filename, char *filetype); void serve_dynamic(int fd, char *filename, char *cgiargs); void clienterror(int fd, char *cause, char *errnum, char *shortmsg, char *longmsg); int main(int argc, char **argv) { int listenfd, connfd; char hostname[MAXLINE], port[MAXLINE]; socklen_t clientlen; struct sockaddr_storage clientaddr; /* Check command-line args */ if (argc != 2) { fprintf(stderr, "usage: %s <port>\n", argv[0]); exit(1); } listenfd = Open_listenfd(argv[1]); while (1) { clientlen = sizeof(clientaddr); connfd = Accept(listenfd, (SA *)&clientaddr, &clientlen); Getnameinfo((SA *) &clientaddr, clientlen, hostname, MAXLINE, prot, MAXLINE, 0); printf("Accepted connection from (%s, %s)\n", hostname, port); doit(connfd); Close(connfd); } } TINY main 반복실행 서버로 명령줄에서 넘겨받은 포트로의 연결 요청 듣는다. ...

2023년 4월 16일 · 8 분 · 배준수

CSAPP 11단원 공부

CHAPTER 11. 네트워크 프로그래밍 웹 검색, 이메일 메시지, 온라인 게임 등 모두가 네트워크 응용을 사용 11.1 클라이언트-서버 프로그래밍 모델 모든 네트워크 응용 프로그램은 Client-server 모델에 기초 : 1개의 server process + 1개 이상의 client process로 구성 SERVER : 일부 리소스를 관리, 조작해서 Client를 위한 일부 서비스를 제공 예시 웹 서버 : 디스크 파일들을 관리, CLIENT를 대신해서 이들을 가져오고 실행 FTP 서버 : CLIENT를 위해 저장하고 읽어오는 디스크 파일들 관리 이메일 서버 : CLIENT를 위해서 읽고 갱신하는 스풀 파일 관리 CLIENT-SERVER 모델의 근본적인 연산은 트랜잭션(transaction), ...

2023년 4월 15일 · 20 분 · 배준수