MAXTACK 문제 관련하여 다시 질문드립니다.

  • sven
    sven

    MAXTACK

    연산의 결과는 push 된 원소들 각각에 -1 을 곱하거나 곱하지 않은 채로 더한 것과 같습니다. pair 로 push 된 index 와 부호를 저장하였고, stack 의 원소들 각각은 위의 pair 들의 set으로 표현하였습니다. (set 을 특별히 쓸 이유는 없는 것 같은데요, 그냥 연습용으로...)
    4 가지 instruction 각각에 맞게 연산을 진행하고, 이후에는 사전순으로 맨 앞의 수열을 구하기 위해 push 된 원소들을 크기 순으로 정렬하여 계수가 -1 인 자리 -> 계수가 1인 자리, 왼쪽 -> 오른쪽으로 수를 채웠습니다.
    어느 부분이 문제인지 잘 모르겠습니다 ㅜㅜ
    아래는 테스트 케이스들의 결과입니다.

    5

    8
    push
    push
    add
    push
    subtract
    negate
    push
    add
    5 3 2 10

    --> 16
    --> 3 5 2 10

    16
    push
    push
    add
    push
    push
    subtract
    push
    push
    add
    push
    push
    subtract
    add
    subtract
    negate
    add
    8 7 6 5 4 3 2 1

    --> 16
    --> 5 6 1 7 2 3 8 4

    6
    push
    push
    subtract
    push
    subtract
    negate
    1 2 3

    --> 0
    --> 1 3 2

    22
    push
    push
    add
    push
    add
    push
    add
    push
    add
    push
    add
    push
    add
    push
    add
    push
    add
    push
    push
    add
    negate
    add
    1 2 3 4 5 6 7 8 9 10 11

    --> 60
    --> 3 4 5 6 7 8 9 10 11 1 2

    12
    push
    push
    subtract
    push
    push
    subtract
    push
    push
    subtract
    add
    add
    negate
    1 2 3 4 5 6

    --> 9
    --> 4 1 5 2 6 3

    #include <iostream>
    #include <vector>
    #include <cassert>
    #include <queue>
    #include <set>
    #include <stack>
    #include <algorithm>
    #include <stdio.h>
    #include <cstring>
    #include <cmath>
    
    using namespace std;
    struct cmp
    {
      bool operator()(const pair<int, bool> &A, const pair<int, bool> &B)
      {
        return A.first < B.first;
      }
    };
    typedef set <pair <int, bool>, cmp > X;
    
    #define EACH(x) for(X::iterator it=x.begin(); it!=x.end(); ++it)
    
    void solve();
    
    int main()
    {
      int T;
      scanf("%d", &T);
      while(T--)
        solve();
    }
    
    void solve()
    {
      char D[4][10] = {"push", "add", "subtract", "negate"};
      stack <X> A;
      int N;
      int pushed = 0;
      int summed = 0;
      scanf("%d", &N);
      for(int i=0; i<N; i++)
      {
        char temp[10];
        scanf("%10s", temp);
        assert(pushed - summed == A.size());
        if(!strcmp(temp, D[0]))
        {
          X temp;
          temp.insert(make_pair(pushed, true));
          A.push(temp);
          pushed++;
        }
        else if(!strcmp(temp, D[1])) 
        {
          summed++;
          assert(A.size() >= 2);
          X x = A.top();
          A.pop();
          X y = A.top();
          A.pop();
          X z;
    //      set_union(x.begin(), x.end(), y.begin(), y.end(), inserter(z, z.begin()));
          EACH(x) z.insert(make_pair((*it).first, (*it).second));
          EACH(y) z.insert(make_pair((*it).first, (*it).second));
          A.push(z);
        }
        else if(!strcmp(temp, D[2]))
        {
          summed++;
          assert(A.size() >= 2);
          X x = A.top();
          A.pop();
          X y = A.top();
          A.pop();
          X z;
          EACH(x) z.insert(make_pair((*it).first, (*it).second));
          EACH(y) z.insert(make_pair((*it).first, !(*it).second));
          A.push(z);
        }
        else if(!strcmp(temp, D[3]))
        {
          X x = A.top();
          A.pop();
          X z; 
          EACH(x) z.insert(make_pair((*it).first, !(*it).second));
          A.push(z);
        }
        else
          assert(false);
      }
      assert(pushed - summed == A.size());
      assert(A.size() == 1);
    
      vector <long> B;
      for(int i=0; i<pushed; i++)
      {
        long temp;
        scanf("%ld", &temp);
        B.push_back(temp);
      }
      sort(B.begin(), B.end());
      int b_index = 0;
      long ans[pushed];
      long sum = 0;
      EACH(A.top())
        if(!(*it).second)
        {
          assert((*it).first < pushed);
          ans[(*it).first] = B[b_index];
          sum -= B[b_index];
          b_index++;
        }
      EACH(A.top())
        if((*it).second)
        {
          assert((*it).first < pushed);
          ans[(*it).first] = B[b_index];
          sum += B[b_index];
          b_index++;
        }
      assert(b_index == pushed);
      cout << sum << endl;
      for(int i=0; i<pushed; i++)
        cout << ans[i] << " ";
      cout << endl;
    
    }
    

    10년 전
6개의 댓글이 있습니다.
  • wookayin
    wookayin

    long, %ld 는 64bit 가 아닐 수도 있습니다.


    10년 전 link
  • sven
    sven

    으어어.... 감사합니다. 인풋이랑 아웃풋 때문에 19번 틀렸네요 ㅠㅠ


    10년 전 link
  • sven
    sven

    찾아보니 gcc 라고 다 같은 사이즈를 쓰지는 않나보네요. 감사합니다.


    10년 전 link
  • Being
    Being

    출제자 님이 좋아합니다.


    10년 전 link
  • wookayin
    wookayin

    long 은 C++ 표준 스펙에 32bit 이상이라고만 정의되어 있습니다. 예를들어 linux x64 플랫폼에서는 64bit 일 수 있지요.

    자세한 것은 http://en.cppreference.com/w/cpp/language/types 를 참고하시고, 항상 64bit 정수를 다룰 때는 주의하시면 됩니다 ^^


    10년 전 link
  • Being
    Being

    자신이 없으시면 uint32_t 같은 explicit type을 사용하세요.


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