semo_semo   5년 전

DFS 백트래킹?이 맞는지는 모르겠는데 그 부분을 공부한다고 나름 공부를 하고 짠 코드인데.. 여러 테스트케이스를 머리를 짜내서 돌려봤는데 제가 생각해낸거는 다 돌아가더라구요ㅜ

  1. 혹시 코드상의 오류나 반례 테스트 케이스가 눈에 보이시는 분들 조언 부탁드립니다
  2. DFS Backtracking이라 해야하는지 Backtracking이라 해야하는지 잘 모르겠지만, 이런 전수조사 느낌의? Backtracking 알고리즘을 이용한 풀이를 작성할 때 머릿속이 너무 복잡해서 정리가 안되는데.. Backtracking알고리즘 코드를 짤 때 신경써야 할 부분, 혹은 이 부분을 염두에 두고 코드를 작성하면 보다 수월하게 접근할 수 있다 하는 팁 같은거 있으신 분들 많은 조언 부탁드립니다ㅜ


이 문제풀이를 할 때 작성한 코드는 아래 첨부하겠습니다.

반례가 눈에 안보이시더라도 그와 상관없이 백트래킹 관련해서 많은 팁 주시면 정말 감사드리겠습니다. 혼자 공부하려니 힘이드네요..

semo_semo   5년 전

그리고 백트래킹 관련하여 기본부터 차근차근 쌓아올릴 수 있게 추천해주실만한 문제들 있으면 추천 부탁드립니다!

쉬운 것 부터 단계단계 풀어나가보고 싶어서요

seico75   5년 전

문제에 출력이 "사전식"이어야 한다는 조건이 있습니다.

즉, 출력되는 문자열이 사전식으로 소트가 되어야 한다는 이야기이며 

이것만 수정을 하면 통과하는 것을 확인했습니다.

잘 작성하신 것 같지만... 좀 문제를 단순화 시킬 수도 있을 것 같습니다.

- 지금은 처음에 C개 문자 중에 하나가 오고 그 다음에 C개 문자 중에서 중복되지 않는 것 오고...

- 이렇게 만들어진 문자열이 자음모음 규칙이 맞나

- 사전순으로 배열이 되었나.

이런 순서인데..

- C개의 문자를 소팅하고

- 1번 문자를 넣을까 말까 / 2번 문자를 넣을까 말까 ....

- 문자열이 L개 맞나?

- 자음모음규칙 맞나?

이렇게 처리하면 좀 단순해 질 것 같습니다.

seico75   5년 전

완전탐색은 아래 문제집은 어떨까요?

https://www.acmicpc.net/workbo... 

https://www.acmicpc.net/workbo...

semo_semo   5년 전

아아 사전식 출력을 놓치고있었군요ㅜㅠ 친절하신 답변 감사합니다. 

백트래킹 문제들을 풀때마다 재귀를 따라가다보면 머릿속에서 생각이 자꾸 꼬여버려서 너무 힘드네요ㅠㅜ

백트래킹 추천해주신 문제집으로 풀어나가면서 공부해보겠습니다 흐


혹시 백트래킹 관련된 문제풀때 가지고계신 팁같은게 따로있을까요..? 너무 광범위한 질문일까요 ㅎㅎ.. 제가머리가나쁜건지 백트래킹개념을 잘 모르는건지.. 어렵네요너뮤ㅜ

seico75   5년 전

특별한 팁이랄 것은 잘 모르겠네요.

다 아는 것 처럼 아래와 같은 틀에서..

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년 전

아아 참고해서 많은 도움이됐습니다! 정말 감사합니다

늘 친절하신 설명 주셔서 감사해요

열심히 해서 백트래킹 마스터해보겠습니당..ㅎㅎ

댓글을 작성하려면 로그인해야 합니다.