D - Even-Odd Game CodeForces - 1472D

D - Even-Odd Game

CodeForces - 1472D

题目大意
有一堆数,两个小孩比赛,小孩A先开始选择某个数,如果是偶数,小孩A加上相应得分,如果是奇数,不加分。然后小孩B在接下来得数中选择某个数,如果是奇数,小孩B加上相应的分,如果是偶数,不加分。
最后比较两个小孩的分数(假设两个人都发挥最佳),如果分数相等输出“tie”,否则输出赢得人的名字。
思路
(这道题是我第一次完整的用优先队列做的ac题,超开心~~)
首先为什么会想到用优先队列 。
这里补充下优先队列的性质,优先队列是有顺序的数列(默认是从大到小) 正好符合本题发挥最佳的要求,其次,优先队列有pop(),可以及时把用过的数pop()掉,十分方便间接。

下面说下这道题的具体思路
首先需要把奇数和偶数分开(这是因为小孩A可以选给自己加分的偶数,也可以选较大的奇数,从而使小孩B选不到较大的奇数,是自己有更大的赢的可能)这里要理解一下
因为要把奇数和偶数分开,所以要定义两个优先队列变量,分别存储奇数和偶数。(这里由于优先队列的功能,放进去的数已经排好了顺序从大到小)。然后分别取出两个队列的头进行比较,如果偶数大于奇数,那么小孩A可以选择偶数使自己获得更多的分,相反如果奇数大于偶数,那么小孩A应该选择奇数来组织小孩B得到更大的奇数。最后分别记录小孩A和小孩B的总分进行比较,结果就出来啦!!!
代码如下

#include 
using namespace std;
using ll = long long;
priority_queueJ,O;
const int N=2e5+5;
int a[N];
int main()
{
    int t,n;
    cin >> t;
    while (t--)
    {
        cin >> n;
        for (int i=1; i<=n; i++)
        {
            cin >> a[i];
        }
        while(J.size())J.pop();
        while(O.size())O.pop();
        int j=1,g=1;
        for(int i=1; i<=n; i++)
        {
            if(a[i]%2==0) {O.push(a[i]);}
            if(a[i]%2!=0) {J.push(a[i]);}
        }
        ll x=0,y=0;int a,b;
        while(J.size()||O.size())
        {
            if (O.size()!=0)a=O.top();
            else a=0;
            if (J.size()!=0)b=J.top();
            else b=0;
            if(a>=b){
                x=x+a;
                O.pop();}
            else J.pop();
            if (O.size()!=0){a=O.top();}
            else a=0;
            if (J.size()!=0){b=J.top();}
            else b=0;
            if(O.size()==0&&J.size()==0)break;
            if(a<=b){
            y=y+b;
            J.pop();}
            else O.pop();
        }
        if (x==y){cout << "Tie\n";}
        if (x-y> 0){cout << "Alice\n";}
        if(x

题目链接
https://vjudge.net/problem/CodeForces-1472D/origin
可以复制去看哦~

你可能感兴趣的:(算法,队列)