結果

問題 No.190 Dry Wet Moist
ユーザー codershifthcodershifth
提出日時 2016-01-10 20:57:52
言語 C++11
(gcc 11.4.0)
結果
AC  
実行時間 387 ms / 2,000 ms
コード長 3,311 bytes
コンパイル時間 1,846 ms
コンパイル使用メモリ 166,908 KB
実行使用メモリ 13,452 KB
最終ジャッジ日時 2023-10-19 19:50:58
合計ジャッジ時間 5,893 ms
ジャッジサーバーID
(参考情報)
judge11 / judge14
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 1 ms
4,348 KB
testcase_01 AC 2 ms
4,348 KB
testcase_02 AC 1 ms
4,348 KB
testcase_03 AC 1 ms
4,348 KB
testcase_04 AC 1 ms
4,348 KB
testcase_05 AC 2 ms
4,348 KB
testcase_06 AC 2 ms
4,348 KB
testcase_07 AC 3 ms
4,348 KB
testcase_08 AC 3 ms
4,348 KB
testcase_09 AC 2 ms
4,348 KB
testcase_10 AC 2 ms
4,348 KB
testcase_11 AC 2 ms
4,348 KB
testcase_12 AC 143 ms
8,808 KB
testcase_13 AC 204 ms
10,284 KB
testcase_14 AC 137 ms
8,700 KB
testcase_15 AC 220 ms
10,812 KB
testcase_16 AC 314 ms
12,924 KB
testcase_17 AC 22 ms
4,620 KB
testcase_18 AC 101 ms
7,756 KB
testcase_19 AC 299 ms
12,924 KB
testcase_20 AC 168 ms
9,756 KB
testcase_21 AC 13 ms
4,412 KB
testcase_22 AC 351 ms
13,452 KB
testcase_23 AC 387 ms
13,452 KB
testcase_24 AC 387 ms
13,452 KB
testcase_25 AC 1 ms
4,348 KB
testcase_26 AC 2 ms
4,348 KB
testcase_27 AC 183 ms
9,556 KB
testcase_28 AC 56 ms
6,240 KB
testcase_29 AC 79 ms
7,004 KB
権限があれば一括ダウンロードができます

ソースコード

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)) でみつかる
            //
            // multiset をつかえば配列の要素の削除・更新ができる。
            //

            int nDry = 0;
            {
                multiset<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;
            {
                multiset<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;
            {
                multiset<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