Round C APAC Test 2017 Problem D. Soldiers

Problem D. Soldiers

General Alice and General Bob are playing a war game. There are N soldiers in the game. Each soldier has two stats: attack and defense.

Before the game starts, General Alice and General Bob will take turns selecting soldiers, with General Alice going first. In each turn, a player can select one soldier, as long as that soldier either has an attack stat greater than each of the attack stats of all soldiers selected so far, or has a defense stat greater than each of the defense stats of all soldiers selected so far. To be precise: let Ai and Di be the attack and defense values for the i-th soldiers, for i from 1 to N, and let S be the set of soldiers that have been selected so far. Then a player can select soldier x if and only if at least one of the following is true:

  • Ax > As for all s in S
  • Dx > Ds for all s in S
If no selection can be made, then the selection process ends and the players start playing the game.

General Alice wants to select more soldiers than General Bob, and General Bob wants to avoid that. If both players play optimally to accomplish their goals, can General Alice succeed?

Input

The first line of each case contains a positive integer N, the number of soldiers. N more lines follow; the i-th of these line contains two integers Ai and Di, indicating the attack and defense stats of the i-th soldier.

Output

For each test case, output one line containing Case #x: y, where x is the test case number (starting from 1) and y is YES or NO, indicating whether General Alice can guarantee that she selects more soldiers than General Bob, even if General Bob plays optimally to prevent this.

Limits

1 ≤ T ≤ 10;
1 ≤ AkDk ≤ 10000.

Small dataset

1 ≤ N ≤ 200.

Large dataset

1 ≤ N ≤ 4000.

Sample


Input 
 

Output 
 
3
3
10 2
1 10
10 3
3
10 1
10 10
1 10
3
10 2
1 10
4 9

Case #1: NO
Case #2: YES
Case #3: YES


Solution

#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <stack>
#include <list>
#include <iterator>
#include <unordered_set>
#include <unordered_map>
using namespace std;

typedef long long ll;

bool get_res(const vector<pair<int, int> >& soldiers, vector<bool> deleted, int N)
{
    int MAXA, MAXD;
    int n = N;
    while (n > 0)
    {
        MAXA = MAXD = 0;
        for (int i = 0; i < N; i++)
        {
            if (!deleted[i])
            {
                MAXA = max(soldiers[i].first, MAXA);
                MAXD = max(soldiers[i].second, MAXD);
            }
        }

        for (int i = 0; i < N; i++)
        {
            if (!deleted[i])
            {
                if (soldiers[i].first == MAXA)
                {
                    if (soldiers[i].second == MAXD)
                    {
                        return true;
                    }
                    else
                    {
                        n--;
                        deleted[i] = true;
                    }
                }
                else if (soldiers[i].second == MAXD)
                {
                    n--;
                    deleted[i] = true;
                }
            }
        }
    }

    return false;
}

int main(int argc, char* argv[])
{
#ifndef TEST
    if (argc != 2)
    {
        cout << "Invalid input" << endl;
        return 1;
    }

    string input = argv[1];  
    string output = input.substr(0, input.length() - 2) + "out";  
    freopen(input.c_str(), "r", stdin);
    freopen(output.c_str(), "w", stdout);  
#endif

    const int MAXN = 4000;
    vector<pair<int, int> > soldiers(4000);
    vector<bool> deleted(4000);

    int T, N;
    int A, D;

    cin >> T;
    for (int i = 1; i <= T; i++)
    {
        cin >> N;
        for (int j = 0; j < N; j++)
        {
            cin >> A >> D;
            soldiers[j] = make_pair(A, D);
            deleted[j] = false;
        }
        
        bool flag = get_res(soldiers, deleted, N);

        cout << "Case #" << i << ": " << (flag ? "YES" : "NO") << endl;
    }

    fclose(stdin);
    fclose(stdout);

    return 0;
}


Note

The solution to problem D is actually deceptively simple. Let's say whoever picks last wins.

If there are no soldiers, then Alice loses, because she has no moves. Otherwise, let the highest attack of the soldiers be maxA and the highest defense be maxD. We have two cases:

1. If there is a soldier with (Ai, Di) = (maxA, maxD), then Alice picks this soldier and wins immediately.

2. Otherwise, the players will never pick any soldier with attack maxA or defense maxD. The reason for this is that, if one player picks a soldier with attack maxA, the other immediately picks any soldier with defense maxD and wins. Therefore, as no soldiers with attack maxA or defense maxD will ever be picked, we can simply delete these soldiers and start again.

The straightforward O(n^2) implementation is good enough!


Reference

https://code.google.com/codejam/contest/6274486/dashboard#s=p3

http://codeforces.com/blog/entry/47181

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

EnjoyCodingAndGame

愿我的知识,成为您的财富!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值