Problem D. Soldiers Google APAC 2017 University Test Round C

来源:互联网 发布:兰州ps软件班 编辑:程序博客网 时间:2024/06/06 20:31

这种game theory的题目我是最不会的了T_T

如果存在一个soldier,A和D均为最大,那么先手第一轮选这个solder就一定会赢。

否则,将A最大的solder集合记为setA,将B最大的solder集合记为setB。那么这两个set双方都不会选。eg., 如果一方选择了setA中的一个solder,另一方选择setB中的一个solder,就不再存在符合条件的solder x,游戏结束。

如果Alice选了setA or setB中的solder,Alice和Bob的solder数量一样多。如果Bob选了setA or setB中的solder,Alice和 比Bob的solder数量多一个。所以该策略对双方都不利。

Then,把这些solder删除,结果不变。

如果除去这两个set的solder,没有solder可以选择,那么Alice也是输的,因为Alice必须要从中选一个,然而这是个必输 策略。

#include<iostream>#include<stdio.h>#include<cstdio>#include<string>#include<cmath>#include<stdlib.h>#include<algorithm>#include<string.h>#include<cstring>#include<vector>#include<queue>#include<map>using namespace std;//2017 RoundC Problem D. Soldiersint T;const int maxn=4010;int N;int A[maxn];int D[maxn];bool ans;bool deleted[maxn];vector<int> findmaxidx(int arr[]){    int maxi=0;    vector<int>vec=vector<int>();    for(int i=0;i<N;i++)    {        if(deleted[i]==true)        {            continue;        }        if(maxi<arr[i])        {            maxi=arr[i];        }    }    for(int i=0;i<N;i++)    {        if(deleted[i]==false&&arr[i]==maxi)        {            vec.push_back(i);        }    }    return vec;}void solve(){    int cnt=N;    while(cnt>0)    {        vector<int>idxa=findmaxidx(A);        vector<int>idxb=findmaxidx(D);        int selected[maxn];        memset(selected,0,sizeof(selected));        for(int i=0;i<idxa.size();i++)        {            selected[i]=1;            for(int j=0;j<idxb.size();j++)            {                selected[j]=1;                if(idxa[i]==idxb[j])                {                    ans=true;                    return;                }            }        }        int num=0;        for(int i=0;i<N;i++)        {            num+=selected[i];        }        if(num==cnt)        {            ans=false;            return;        }        else        {            for(int i=0;i<idxa.size();i++)            {                deleted[idxa[i]]=true;                cnt--;            }            for(int j=0;j<idxb.size();j++)            {                deleted[idxb[j]]=true;                cnt--;            }        }    }}int main(){    freopen("D-large-practice.in","r",stdin);    freopen("output.txt","w",stdout);    scanf("%d", &T);    for(int ca=1;ca<=T;ca++)    {        memset(A,0,sizeof(A));        memset(D,0,sizeof(D));        memset(deleted,false,sizeof(deleted));        ans=false;        scanf("%d",&N);        for(int i=0;i<N;i++)        {            scanf("%d %d",&A[i],&D[i]);        }        solve();        printf("Case #%d: %s\n",ca,ans==true?"YES":"NO");    }    return 0;}


0 0