그리고 백트래킹 관련하여 기본부터 차근차근 쌓아올릴 수 있게 추천해주실만한 문제들 있으면 추천 부탁드립니다!
쉬운 것 부터 단계단계 풀어나가보고 싶어서요
1759번 - 암호 만들기
문제에 출력이 "사전식"이어야 한다는 조건이 있습니다.
즉, 출력되는 문자열이 사전식으로 소트가 되어야 한다는 이야기이며
이것만 수정을 하면 통과하는 것을 확인했습니다.
잘 작성하신 것 같지만... 좀 문제를 단순화 시킬 수도 있을 것 같습니다.
- 지금은 처음에 C개 문자 중에 하나가 오고 그 다음에 C개 문자 중에서 중복되지 않는 것 오고...
- 이렇게 만들어진 문자열이 자음모음 규칙이 맞나
- 사전순으로 배열이 되었나.
이런 순서인데..
- C개의 문자를 소팅하고
- 1번 문자를 넣을까 말까 / 2번 문자를 넣을까 말까 ....
- 문자열이 L개 맞나?
- 자음모음규칙 맞나?
이렇게 처리하면 좀 단순해 질 것 같습니다.
특별한 팁이랄 것은 잘 모르겠네요.
다 아는 것 처럼 아래와 같은 틀에서..
f()
{
종료조건
(early termination 조건)
분기1
분기2
}
이런 구조에 맞춰서 분기1/2 등을 Sub 문제로 생각해서 재귀로 만듭니다.
예를 들면 위 문제는 저는..
void printPassword( int start, int find) { if ( find == L) { if ( isOk( answer) == true) cout << answer << ENDL; return; } if ( start + L - find > C) return; answer[find] = candidates[start]; printPassword( start + 1, find + 1); printPassword( start + 1, find); }
이런식으로 하고,
10597 문제 같은 경우는
bool makeSeq( const char* p, int nth) { if ( nth == N) return true; int n = *p - '0'; if ( n == 0) return false; // 1 digit if ( visited[n] == false) { visited[n] = true; seq[nth] = n; if ( makeSeq( p + 1, nth + 1) == true) return true; visited[n] = false; } // 2 digit if (*(p + 1) == '\0') return false; n = n * 10 + *(p + 1) - '0'; if ( n <= N && visited[n] == false) { visited[n] = true; seq[nth] = n; if ( makeSeq( p + 2, nth + 1) == true) return true; visited[n] = false; } return false; }
이런식으로 했네요..
별로 팁이랄 것이 없네요.. ㅠㅠ
댓글을 작성하려면 로그인해야 합니다.
semo_semo 5년 전
DFS 백트래킹?이 맞는지는 모르겠는데 그 부분을 공부한다고 나름 공부를 하고 짠 코드인데.. 여러 테스트케이스를 머리를 짜내서 돌려봤는데 제가 생각해낸거는 다 돌아가더라구요ㅜ
이 문제풀이를 할 때 작성한 코드는 아래 첨부하겠습니다.
반례가 눈에 안보이시더라도 그와 상관없이 백트래킹 관련해서 많은 팁 주시면 정말 감사드리겠습니다. 혼자 공부하려니 힘이드네요..