- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 선생님 안녕하세요 우선 http://boj.kr/e25eb9ed4cf34c26bf2c12eff66b4e22 강의를 들으면서 나름대로 짜봤더니 시간초과가 나는데 선생님의 코드로 main 부분을 바꾸면 시간초과가 안나는 이유가 궁금합니다! 부족한 지식에 해답을 주시면 감사하겠습니다 ㅠㅠ
큰돌님 코드중에 int& ret = dp[here][visited]; if(ret != -1) return ret; 이 부분이 결국 메모이제이션으로 해석되었는데요. 강의중 {a,b,c} -> d 로 가려고 할때 {a,b,c}의 순서는 상관없다고 말씀해주신게 ret = min(ret, tst(i, visited | (1<<i)) + dist[here][i]) 이 부분을 거치면서 {a,b,c} -> d로 가기 전 이미 최소 경로로 갱신된 상태이기 때문인가요? 즉, 실제로 a->b->c->d와 b->c->a->d의 경로비용은 다르지만 위의 코드로 인해서 이미 최소비용 경로로 {a,b,c} 가 끝난 상황. 이라고 해석하면 될까요?
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 문자를 a로 치환하고 숫자만 뽑으려고 하는데 a의 개수가 달라서 에러가 뜹니다. 방법이 없을까요?? import java.io.*; import java.util.*; public class Main { public static void main(String[] argvs) { Scanner sc = new Scanner(System.in); String s=sc.next(); String str = s.replaceAll("[^0-9]","a"); //a로 치환 int answer= 0; System.out.print(str); } }
- 학습 관련 질문을 남겨주세요. 상세히 작성하면 더 좋아요! - 먼저 유사한 질문이 있었는지 검색해보세요. - 서로 예의를 지키며 존중하는 문화를 만들어가요. - 잠깐! 인프런 서비스 운영 관련 문의는 1:1 문의하기를 이용해주세요. 자바로 작성하니까 시간초과가 나는데, 상관없는 건가요?? import java.io.*; import java.util.*; public class Main { public static void main(String[] argvs) { Scanner sc = new Scanner(System.in); int n=sc.nextInt(); int[] num = new int[n+1]; for(int i=1; i<=n; i++) { num[i] = sc.nextInt(); } Stack<Integer> st = new Stack<>(); int[] answer = new int[n+1]; for(int i=n; i>=1; i--) { //제일 뒤에서 부터 스택에 넣는다.(스택에 넣는 것은 [[인덱스 번호]]를 넣는다) while(!st.isEmpty() && num[i]>num[st.peek()]) { //num배열에서 인덱스 번호에 해당하는 것을 본다. 현재 배열의 값이 스택의 top부분보다 크면 pop한다. 다시말해 스택 안은 오름차순 정렬된다. answer[st.peek()] = i; //정답 배열에 인덱스 값 넣기, st.peek도 인덱스, i도 인덱스 번호 st.pop(); } st.push(i); //스택에 삽입 } for(int i=1; i<=n; i++) { //답 출력 System.out.print(answer[i]+" "); } } }
큰돌님의 풀이에서 value와 합연산을 하는 부분이 이해가 잘 안되어서 조금 고민을 해봤는데 결국 idx번째 비트 켜기와 같다고 생각했습니다. 비트마스킹 강의에서 idx번째 비트 켜기를 void idx번째비트켜기() { int S = 18; int idx = 0; S |= (1 << idx); cout << S << '\n'; } 이렇게 알려주셨는데요. 이를 사용해서 아래와 같이 입력을 받아도 무방한가요? 출력해봤을 땐 똑같이 나오는데 풀이를 value를 써서 하신 이유가 따로 있는지 궁금해서 질문남깁니다. for (int i = 1; i < n + 1; i++) { cin >> s; for (int j = 0; j < s.size(); j++){ if (s[j] == 'T') a[i] |= (1 << j); } cout << a[i] << '\n'; }
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> #define SIZE 20 using namespace std; int main() { char animal[SIZE]; char* ps; cout << "동물 이름을 입력하십시오.\n"; cin >> animal; ps = new char[strlen(animal) +1]; strcpy(ps, animal); cout << "입력하신 동물 이름을 복사하였습니다." << endl; cout << "입력하신 동물 이름은 " << animal << "이고, 그 주소는 " << (int*)animal << " 입니다." << endl; cout << "복사된 동물 이름은 " << ps << "이고, 그 주소는 " << (int*)ps << " 입니다." << endl; delete[] ps; return 0; } 이제는 #include <cstring> 을 추가해야만 작성해주신 코드가 동작하는게 보여지는데 헤더가 기본적으로 가지고 있는 내용이 시간이 지나면서 바뀐걸까요? 아니면 C++ 업데이트를 제가 잘못한건가요?
대학교에서 자료구조를 배우고 있는 학생입니다! 연결리스트의 삽입 및 삭제 시간 복잡도 관련해서 질문이 있습니다. Q. 왜 연결리스트의 삽입과 삭제는 O(1)인가요? 라는 내용에서 왜 이미 노드에 접근했다고 상정하고 시간복잡도를 계산하는지 이해가 가지 않습니다. 제 이해로는 노드에 접근하는 과정까지 시간복잡도 계산에 포함시켜야 한다고 생각하는데 자세한 설명을 듣고싶습니다!
안녕하세요 큰돌 님. 7-D를 풀던 도중 메모이제이션 부분에서 질문드립니다. 저는 메모이제이션을 2차원 배열로 하고자 했는데요, 제가 생각하기에 나무가 2개뿐이기에 이동 횟수에 따라 나무의 위치를 특정할 수 있기 때문에 "1번 움직이면 -> 2번 나무, 2번 움직이면 -> 1번 나무"와 같이 이동 횟수와 나머지 연산을 통해 '현재 위치'를 메모이제이션 하지 않아도 된다는 생각이 들었습니다. 때문에 이동 횟수와 현재 시간만 메모이제이션 하고자 했습니다. 혹시 이런 식의 접근으로는 풀 수가 없는 것일까요? 제가 제출한 코드도 첨부 드립니다. http://boj.kr/7d0a67eaf7b8428e912f596c29a971f1
이에 대해서 chat gpt 에 물어봤는데 " Half-Open Range의 중요성 이 반복자 범위는 "half-open" 범위로 알려져 있습니다. 즉, 시작은 포함되지만 종료는 포함되지 않습니다( [begin, end) ). 이러한 설계는 다음과 같은 이유로 안전성과 효율성을 제공합니다: 범위 초과 방지 : end() 가 마지막 요소의 바로 다음을 가리키므로, 반복 과정에서 마지막 요소를 처리한 후 반복자를 한 번 더 증가시키면 end() 를 가리키게 됩니다. 이 위치는 실제 데이터를 포함하지 않으며, 반복자가 데이터를 벗어난 상태가 되지 않습니다. 따라서 루프에서 it != vec.end() 조건을 검사할 때 정확히 루프가 종료되며, 이는 범위를 초과하여 데이터에 접근하는 일이 없도록 합니다. 일관된 로직 : 모든 표준 알고리즘과 컨테이너 연산은 이 half-open 패턴을 기대합니다. 이로 인해 개발자는 특별한 경우를 고려하지 않고도 일관된 방식으로 코드를 작성할 수 있습니다. 이는 오류 가능성을 줄이고 코드의 가독성을 높여줍니다. " 이렇게 답을 해줬습니다. end()가 마지막 요소를 직접 가리키는 경우 저는 오히려 범위 초과 방지에 더 도움이 된다고 생각하기에 이 설명이 이해가 잘 안 됩니다. 또 chat gpt에서 " std::vector<int> vec = {1, 2, 3}; auto it = vec.begin(); // it는 Index 0을 가리킵니다 (Element: 1) 여기에서 end() 가 마지막 요소를 직접 가리키는 경우 (비표준, 가상 시나리오) 이 경우를 가정하여, vec.end() 가 Index 2, 즉 3 을 가리킨다고 가정해 봅시다. 반복 실행 과정 : it 는 1 을 가리킵니다. it != vec.end() 는 참입니다. 요소 1 을 출력하고 ++it . it 는 2 를 가리킵니다. it != vec.end() 는 참입니다. 요소 2 를 출 력하고 ++it . it 는 3 을 가리킵니다. it != vec.end() 는 참입니다. 요소 3 을 출력하고 ++it . 여기서 문제가 발생합니다. it 를 한 번 더 증가시키면, it 는 vec.end() 를 넘어서 Index 3으로 이동하게 되고, 이 위치는 벡터의 범위를 벗어난 위치입니다. 이 시점에서 다음의 it != vec.end() 검사는 undefined behavior를 초래할 수 있습니다, 왜냐하면 it 가 벡터의 유효 범위를 벗어났기 때문입니다. " 이렇게 말을 했는데 이해가 잘 되지 않습니다. end()가 마지막 요소를 직접 가리키는 경우 it가 3을 가리킬 때 it != vec.end() 는 오히려 거짓이 되고, 3을 출력하기 전에 반복 실행을 멈추기 때문에 오히려 범위 밖으로 나갈 위험이 적다고 생각합니다. (물론 여기서는 3을 출력하지 않기 때문에 잘못된 것이지만). 그래서 chat gpt 가 마지막 요소 다음을 가리키는 게 더 안전하다고 한 이유를 잘 모르겠습니다. 오히려 end()는 마지막 요소 다음을 가리키는 반복자이므로 쓰레기 값을 가리키는 이상한 녀석이라는 생각이 듭니다.
안녕하세요 선생님! 강의 보기 전에 직접 풀어봤는데요, 테스트 케이스도 정답대로 잘나오지만 백준에서는 틀렸다고 나옵니다 ㅠㅠ 파일 개수 입력 패턴 입력 파일 입력 패턴의 첫 번째/마지막 문자와 파일의 첫 번째/마지막 문자가 같다면 DA출력, 아니면 NE출력 몇 번을 확인해봐도 설계에 문제는 없어보이는데요, 어디가 틀려서 오답처리가 되는걸까요? http://boj.kr/8b7b4a2668c0446a92b0c459e4c67c77 #include <iostream> using namespace std; int cnt; string pattern; string input[100]; int main() { cin >> cnt; cin >> pattern; for (int i = 0; i < cnt; i++) cin >> input[i]; for (int i = 0; i < cnt; i++) { if (pattern[0] == input[i][0] && pattern[pattern.size() - 1] == input[i][input[i].size() - 1]) cout << "DA" << endl; else cout << "NE" << endl; } return 0; }
안녕하세요 큰돌님 강의 잘 듣고 있습니다. 3 - I (17071번)를 푸는데 bfs의 경계조건을 바로 밑에 코드에서 for(int next : {here + 1, here - 1, here * 2}){ if(next < 0 || next > max_n || visited[turn % 2][next]) continue; 아래와같이 바꾸면 런타임 에러 (OutOfBounds)가 발생하는데 그 이유가 궁금합니다. for(int next : {here + 1, here - 1, here * 2}){ if(visited[turn % 2][next] || next < 0 || next > max_n) continue;
안녕하세요 선생님 🙂 저번 질문에서 수강평 작성해달라고 말씀해주셨었는데요, 수강평은 강의를 모두 들은 후에 작성하는 것이 맞을 것 같아서 나중에 작성하겠습니다^^ 오늘은 Counting Star 질문이 있습니다. 강의듣기 전에 먼저 풀어봤는데요, 결과 값은 정확히 나오고 있으며 선생님의 풀이와 차이가 있다면 array를 vector로 사용 char가 아닌 int로 for문을 사용 이렇게 2가지의 차이 밖에 없는 것으로 보이지만 백준에 제출하면 자꾸 오답으로 나옵니다 ㅠㅠ 아래는 제가 한 풀이 방식입니다. 의심되는 부분은 for문 안의 if (S[i] == NULL) break; 이 구문인데요, 문자열의 끝이 공백문자열이다보니 이 구문을 통해 공백문자열을 만난다면 break를 통해 반복문을 빠져나오도록 구현하였습니다. 어떤 문제가 있길래 자꾸 오답처리가 되는걸까요? #include <iostream> #include <vector> using namespace std; int main() { string S; cin >> S; vector<int> vec(26); for (int i = 0; i < 26; i++) { if (S[i] == NULL) break; vec[(int)S[i] - 97]++; } for (auto i : vec) cout << i << " "; return 0; }
클래스 전까진 신나게(?) 진행하다가, 동적할당, 구조체(포인터 변수사용),클래스..진입하면서,복습이 본 공부보다 더 오래, 심지어 오락가락하는 중입니다. 전 강의가 20강이라 짧긴 하고,입문용이긴 한데,.. 갖고있는 c++책의 예제를 보니, 연습용으로 풀긴,아는거보다 모르는게 좀더 많은거같고.. 예제를 만들어 복습을 하는 방법밖엔 없지만, .. 공부방향을 가이드 해주실수있나요? 글고, 입문다음엔 기초이거나,중급일거같은데. 언제 나오나요?
안녕하세요 선생님 lower_bound()를 사용하는 방법으로 boj 11053을 풀면 답은 맞지만 로직 흐름이 맞지 않는 테스트 케이스가 있습니다. 4 10 20 30 11 위 input을 입력하면 출력으로 10 0 0 0 10 20 0 0 10 20 30 0 10 11 30 0 이렇게 나옵니다. 이러한 경우를 고려하지 않아도 괜찮나요?