CHILDRENDAY 코드 좀 봐주세요.

  • mihaly
    mihaly

    #include <algorithm>
    #include <cstring>
    #include <deque>
    #include <functional>
    #include <iostream>
    #include <limits>
    #include <list>
    #include <queue>
    #include <stack>
    #include <string>
    #include <utility>
    #include <vector>
    
    using std::cout;
    using std::cin;
    using std::endl;
    using std::max;
    using std::min;
    using std::sort;
    using std::swap;
    using std::greater;
    using std::numeric_limits;
    using std::memset;
    using std::deque;
    using std::list;
    using std::queue;
    using std::stack;
    using std::string;
    using std::vector;
    using std::pair;
    using std::make_pair;
    using std::fill;
    
    // type definitions
    
    
    // global variables
    int const INF = numeric_limits<int>::max();
    bool was_checked[10000]; // [r] r: remainder
    string g;
    unsigned long long n, m;
    unsigned long long digits[10];
    unsigned long long digit_len;
    
    
    // function declarations
    void solve();
    
    
    int main() {
      int test_case;
      cin >> test_case;
      for ( int i = 0; i < test_case; i++ ) {
        solve();
      }
    
      return 0;
    }
    
    
    void solve() {
      // Initialization
      cin >> g >> n >> m;
      digit_len = g.length();
      fill(was_checked, was_checked + 10000, false);
      for ( int i = 0; i < digit_len; i++ ) {
        digits[i] = g[i] - '0';
      }
      sort(digits, digits + digit_len);
    
      // Solve
      queue<string> candidates;
      queue<unsigned long long> remainders;
      queue<unsigned long long> seed;
    
      for ( int i = 0; i < digit_len; i++ ) {
        if ( digits[i] != 0 ) {
          candidates.push(g.substr(i, 1));
          remainders.push((digits[i] + n - m) % n);
          seed.push(digits[i]);
        }
      }
    
      while ( seed.front() < n + m ) {
        string cur = candidates.front();
        unsigned long long r = remainders.front();
        unsigned long long v = seed.front();
        candidates.pop(); remainders.pop(); seed.pop();
    
        for ( int i = 0; i < digit_len; i++ ) {
          unsigned long long c = digits[i];
          string new_candidate = cur + g.substr(i, 1);
          unsigned long long new_v = 10 * v + c;
          unsigned long long new_r = (10 * r + 9 * m + c) % n;
          candidates.push(new_candidate);
          remainders.push(new_r);
          seed.push(new_v);
        }
      }
    
      while ( !candidates.empty() ) {
        string cur = candidates.front();
        unsigned long long r = remainders.front();
        candidates.pop(); remainders.pop();
        if ( r == 0 ) {
          cout << cur << endl;
          return;
        }
        was_checked[r] = true;
    
        for ( int i = 0; i < digit_len; i++ ) {
          unsigned long long c = digits[i];
          unsigned long long new_r = (10 * r + 9 * m + c) % n;
          if ( was_checked[new_r] ) continue;
          string new_candidate = cur + g.substr(i, 1);
          candidates.push(new_candidate);
          remainders.push(new_r);
        }
      }
    
      cout << "IMPOSSIBLE" << endl;
    
      // Ending
    }
    

    JMBook으로 공부하고 있는데요 항상 먼저 풀어보고 정 못 풀겠다싶으면 답을 보고 이번 경우처럼 풀 수 있을 것 같으면 풀어보거든요.

    제 생각에 구현한 아이디어는 맞느 것 같은데 샘플데이터도 다 정답으로 나오는데 제출하기만 하면 오답으로 나오네요.

    어떤 데이터에서 빵꾸가 났는지도 모르니 잘 모르겠습니다.
    자꾸 틀려서 책을 봤는데 핵심 아이디어는 같다고 생각하거든요.
    구현이 완전 다르긴 하지만 틀렸다고는 생각이 들지 않습니다.
    (물론 제 코드가 훨씬 느려터져요)

    일단 속도적인 면은 차치하고 왜 정확하게 돌아가지 않는지를 알고싶은데 저는 도저히 감이 안 오네요.

    도와주세요 ㅠㅠ

    감사합니다.


    10년 전
3개의 댓글이 있습니다.
  • Kureyo
    Kureyo

    음 digits랑 g를 같이 쓰시는데 digits만 정렬되도 괜찮은가요?


    10년 전 link
  • JongMan
    JongMan

    1 천재..


    10년 전 link
  • mihaly
    mihaly

    //Kureyo
    허... 전혀 생각도 못했네요.
    역시 이유없는 오답은 없군요.
    한 번 다시 해보겠습니다.

    감사합니다.


    10년 전 link
  • 정회원 권한이 있어야 커멘트를 다실 수 있습니다. 정회원이 되시려면 온라인 저지에서 5문제 이상을 푸시고, 가입 후 7일 이상이 지나셔야 합니다. 현재 문제를 푸셨습니다.