안녕하세요 큰돌 강사님 코드에 대해 질문있습니다 공유 코드입니다 http://boj.kr/6afa87cbba6042c59e5314d9cd919887 문자형 백터에 연산자를 모두 넣고 연산자 인덱스를 백트레킹하여 순열을 구한 뒤 백터에 대입해서 풀었습니다. 해설에 있는 코드와 실행시간 차이가 꽤 많이 나는데 두 코드가 어떤 부분에서 효율성의 차이가 나는지 궁금하여 질문 남깁니다.
위 문제를 파이썬으로 시도했습니다. 몇 주 동안 cpp하다가 파이썬으로 하니 파이썬이 불편함이 있네요.. 아래 코드를 실행한 경우, 시간 초과가 떴습니다. 제 생각에는 cpp 내용으로 파이썬 문법으로 그대로 옮겨 적은 거나 마찬가지라고 생각하는데요. from sys import stdin def main(): ret = 0 ans = [] n, m = map(int, stdin.readline().split()) visited = [0 for _ in range(n + 1)] tree = [[] for _ in range(n + 1)] def dfs(root: int): visited[root] = 1 cnt = 1 for there in tree[root]: if not visited[there]: cnt += dfs(there) return cnt for _ in range(m): a, b = map(int, stdin.readline().split()) tree[b].append(a) for i in range(1, n): cnt = 0 visited = [0 for _ in range(n + 1)] if len(tree[i]) != 0 and not visited[i]: cnt = dfs(i) if cnt > ret: ans.clear() ret = cnt ans.append(i) elif cnt == ret: ans.append(i) s = "" for i in ans: s += str(i) + " " print(s) if __name__ == "__main__": main() cpp 쓰다가 파이썬을 쓰니 초기화하는 것도 불편하고, 시간도 많이 걸립니다. (오랜만에 파이썬으로 다시 짜보면 무슨 느낌일지 궁금해서 시도해봤습니다. 아직은 병행하지 않고, 강의 완주 후에 파이썬으로 해볼 생각입니다. 파이썬을 사용하려는 이유는 파이썬을 사용하는 백엔드 회사에 들어갈려고 하거든요. 백엔드로 취업할려면 자바 스프링하라는 영상을 이미 시청했습니다.) main 안에다가 변수를 선언하고 그 안에 dfs 함수를 사용해서 클로저 방식으로 사용해봤는데요. 클로저를 사용 안하고 아래 조건문 안에 선언한 후, if __name__ == "__main__": ... visited = [0 for _ in range(n + 1)] main() 아래 코드처럼 dfs()를 호출하기 전에 visited를 초기화했음에도 불구하고도, for i in range(1, n): cnt = 0 visited = [0 for _ in range(n + 1)] if len(tree[i]) != 0 and not visited[i]: cnt = dfs(i) dfs()는 main()을 호출하기 전 visited를 인식하여 문제 풀이에 에러가 발생하는 것 같습니다. 일반적으로 변수를 선언한 후, 초기화하면서 변수에 그 값을 담는 방식이라면 파이썬은 이와 달리 변수 이름이 그 값에 라벨링처럼 지시하는 방식이라서 새롭게 변수를 생성하여 다른 변수로 인식하는 것 같습니다. global 이나 nonlocal 로 선언하여 사용하는 방식이 있으나, 이런 경우 시간 초과가 발생하더군요. 어떻게 해결할 수 있을까요?
일단 먼저 풀어봤는데, 객체지향으로 풀려고 Player라는 클래스를 생성 후 몸무게와 키를 저장해 이중 for문으로 풀었는데 통과해버렸습니다. 해당 코드는 150~200ms정도가 나오는데 통과하는게 정상인건지 궁금해서 여쭤봅니다. import java.util.Scanner; class Player { int height; int weight; public Player(int height, int weight) { this.height = height; this.weight = weight; } } public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); Player[] players = new Player[n]; for (int i = 0; i < n; i++) { int height = sc.nextInt(); int weight = sc.nextInt(); Player player = new Player(height, weight); players[i] = player; } System.out.println(solution(n, players)); } private static int solution(int n, Player[] players) { int answer = n; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (players[i].height < players[j].height && players[i].weight < players[j].weight) { answer--; break; } } } return answer; } }
안녕하세요. 두 로직이 같은 것 같은데 하나는 맞고 하나는 틀려서 질문드립니다. 부분합 계산하는 로직은 똑같은데, 답지 풀이와 다르게 처음에 부분합을 구하고 한 칸씩 옮기면서 다음 값들을 빼고 더하는 로직입니다. <맞는 코드> http://boj.kr/71648b379df54b9da80fe0b80ec8ca33 #include<bits/stdc++.h> using namespace std; int N, K, num; vector<int> temperatures; int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> N >> K; for (int i = 0; i < N; i++) { cin >> num; temperatures.push_back(num); } int sum = 0; for (int i = 0; i < K; i++) { sum += temperatures[i]; } int ret = -10000000; ret = max(sum, ret); for (int j = K; j < N; j++) { sum = sum + temperatures[j] - temperatures[j - K]; ret = max(sum, ret); } cout << ret << "\n"; } <틀린 코드> http://boj.kr/c2a7e69a69f6426d87429b3920570c4c #include<bits/stdc++.h> using namespace std; int N, K, j; vector<int> temperatures; int main(){ ios_base::sync_with_stdio(false); cin.tie(NULL); cout.tie(NULL); cin >> N >> K; for (int i = 0; i < N; i++) { int num = 0; cin >> num; temperatures.push_back(num); } int sum = 0; for (int i = 0; i < K; i++) { sum += temperatures[i]; } int ret = -10000000; ret = max(sum, ret); j = K; do { sum = sum + temperatures[j] - temperatures[j - K]; ret = max(sum, ret); j++; } while (j < N); cout << ret << "\n"; } 사실 변경점이 do-while문을 for문으로 바꾼 것 밖에 없는데 맞더라구요... 혹시 제가 발견하지 못한 차이점이 있을까요? 좋은 강의 감사합니다. ㅎㅎ
강사님 강의중에 파이썬 강의가 두 개 있고, 두 강의 모두 입문용으로 되어있는데 커리큘럼을 보면 내용이 겹치는 것 같은데 [ 입문자를 위한 코딩테스트 핵심(이론과 문제풀이) [Python] ]강의는 요약, [ 파이썬 알고리즘 문제풀이 입문(코딩테스트 대비) ]강의는 전체적으로 학습하는걸로 이해하고 이 강의만 들어도 될까요?
안녕하세요, 틀린 코드에서 일부를 바꿨더니 맞았는데 이해가 되지 않아 질문을 드립니다. cost <= minCost 일때 최소 비용과 선택된 항목들을 갱신할 경우 사전순으로 뒤쪽인 것이 덮어쓰기 때문에 sort가 반드시 필요하게 되지만 cost < minCost일때만 갱신할 경우 앞쪽에서 같은 비용인게 먼저 나왔다면 뒤에선 갱신되지 않기 때문에 사전순으로 앞쪽인 답이 나온다고 생각했습니다. for문을 오름차순으로 돌리고 있기에 사전순이 뒤집힐 이유도 없을텐데 어디서 문제가 생기는 걸까요? http://boj.kr/c09cb2b0628143d48288d23ea6a78b82
import java.util.*; class Main { public char solution(int n, String s){ int[] cnt = new int[n]; // 알파벳 등장 횟수 배열 char[] ch = s.toCharArray(); for (int i = 0; i < n; i++) { cnt[ch[i]-65]++; // count배열에 a,b,c,d,e 투표결과 저장 } int max = Integer.MIN_VALUE, answer =0; for(int i = 0; i<5; i++){ // count배열의 인덱스 0,1,2,3,4만 체크 if(cnt[i] > max){ answer = i; max = cnt[i]; } } return (char)(answer+65); } public static void main(String[] args){ Main T = new Main(); Scanner kb = new Scanner(System.in); int n=kb.nextInt(); String str=kb.next(); System.out.println(T.solution(n, str)); } } 이렇게 짜도 괜찮을까요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 안녕하세요 선생님!! 이 문제를 sort로도 풀 수 있을까요? 주어진 문자열 두개를 split해서 sort하고 join한 값이 일치하느냐에 따라서 answer를 반환하는 로직을 세워봤습니다. 이렇게 풀어도 문제는 없을까요? function solution(str1, str2) { let answer = ""; let sortStr1 = str1.split("").sort(); let sortStr2 = str2.split("").sort(); if (sortStr1.join("") == sortStr2.join("")) { answer = "YES"; } else { answer = "NO"; } return answer; }
안녕하세요. 첫번째 링크는 해설 듣기 전 제가 작성한 코드고 두번째 링크는 큰돌님 정답 코드입니다. 먼저 제가 짠 코드가 괜찮은 코드인지 의견 듣고 싶고, 또 큰돌님께서 짠 코드중 cnt[a - 'a] 이 부분이 이해가 가지 않습니다. 'a'가 아스키코드인 97로 변한다는 것은 이해했습니다. 그런데 a는 타입이 char니까 baekjoon을 입력받으면 반복문으로 들어갔을땐 cnt[b - 97], cnt[a - 97], cnt[e - 97]... 이렇게 되야하는게 아닌가요..? 실제 작동은 cnt[98 - 97], cnt[97 - 97], cnt[101 - 97]이렇게 되는데 char 타입의 a가 왜 아스키코드로 변하는지 잘 모르겠습니다. 감사합니다. http://boj.kr/e1b91e80fb9d4a68a4e83d27661576c5 https://www.acmicpc.net/source/share/1a1898996c8542889b32b4c1b2498dd0
안녕하세요, 큰돌 강사님!! 졸업하고 취준 기간에도 꾸준히 학습을 하면서 도움을 받고 있습니다. 지금 BFS/DFS 복습을 하면서 궁금증이 생긴 것이 있는데, 코드 상으로 void dfs(int y, int x){ visited[y][x]=1; for(int i=0; i<4; i++){ if(...visited[ny][nx]) continue; } } 와 visited[y][x]=1 코드 없이 그냥 dfs를 하는 것의 차이는 무엇인 가요? 2주차에서의 dfs와 3-C 인구이동에서의 dfs의 차이점이 궁금합니다~~