結果

問題 No.190 Dry Wet Moist
ユーザー codershifthcodershifth
提出日時 2016-01-10 20:43:57
言語 C++11
(gcc 11.4.0)
結果
WA  
実行時間 -
コード長 3,291 bytes
コンパイル時間 1,356 ms
コンパイル使用メモリ 165,352 KB
実行使用メモリ 13,312 KB
最終ジャッジ日時 2024-09-19 15:58:34
合計ジャッジ時間 5,105 ms
ジャッジサーバーID
(参考情報)
judge4 / judge1
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
5,248 KB
testcase_01 AC 1 ms
5,376 KB
testcase_02 WA -
testcase_03 WA -
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 WA -
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 WA -
testcase_23 AC 255 ms
13,312 KB
testcase_24 WA -
testcase_25 WA -
testcase_26 AC 1 ms
6,944 KB
testcase_27 WA -
testcase_28 WA -
testcase_29 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <bits/stdc++.h>

typedef long long ll;
typedef unsigned long long ull;

#define FOR(i,a,b) for(int (i)=(a);i<(b);i++)
#define REP(i,n) FOR(i,0,n)
#define RANGE(vec) (vec).begin(),(vec).end()

using namespace std;


class DryWetMoist {
public:
    void solve(void) {
            int N;
            cin>>N;
            vector<int> A(2*N);
            REP(i,2*N) cin>>A[i];

            // まともに計算すると O(N!) になってしまう。
            //
            // まず Moist を最大化する組み合わせに注目する
            // Moist になるには (a,-a) なる組み合わせしかありえないので、
            // 貪欲法で計算すればよい。ソートしておけば O(N*log(N)) で計算できる。
            //
            // 同様に Dry なものを作るには貪欲法で a<0 のとき (a,b) (b<-a なる最大の b)
            //        Wet なものを作るには        a>0 のとき (a,b) (b>-a なる 最小の b)
            // なる b を選べば良い。
            // これらも二分探索で O(N*log(N)) でみつかる
            //
            // set をつかえば配列の要素の削除・更新ができる。
            //

            int nDry = 0;
            {
                set<int> S(RANGE(A));
                while (!S.empty())
                {
                    auto beg = S.begin();
                    int  a = *beg;

                    if (a >= 0)
                        break;

                    S.erase(beg); // 重複検索しないように先に削除
                    auto found = S.lower_bound(-a);
                    if (found != S.begin())
                    {
                        --found;
                        assert(a+*found <0);
                        ++nDry;
                        S.erase(found);
                    }
                }
            }

            int nWet = 0;
            {
                set<int> S(RANGE(A));
                while (!S.empty())
                {
                    // 大きいものから取り出す
                    auto it = S.end();
                    --it;
                    int  a = *it;

                    if (a < 0)
                        break;

                    S.erase(it);
                    auto found = S.upper_bound(-a);
                    if (found != S.end() && a + *found > 0)
                    {
                        ++nWet;
                        S.erase(found);
                    }
                }
            }

            int nMoist = 0;
            {
                set<int> S(RANGE(A));
                while (!S.empty())
                {
                    auto beg = S.begin();
                    int  a = *beg;

                    S.erase(beg);

                    auto found = S.lower_bound(-a);
                    if (found != S.end() && *found == -a)
                    {
                        ++nMoist;
                        S.erase(found);
                    }
                }
            }

            cout<<nDry<<" "<<nWet<<" "<<nMoist<<endl;
    }
};

#if 1
int main(int argc, char *argv[])
{
        ios::sync_with_stdio(false);
        auto obj = new DryWetMoist();
        obj->solve();
        delete obj;
        return 0;
}
#endif
0