zoj 3757 Alice and Bob and Cue Sports 模拟

    两个人打台球,初始状态为n个编号不同的球和一个母球(编号为0),每个球的分数即它的编号,每次操作时,当前的目标球为台面上球的最小值,操作犯规的话会给对手加上若干分,犯规的情况有:

1  母球没有打到任何球,对手+目标球的分数

2 母球没有落袋,但是母球第一次撞击没有撞到目标球,或者是第一次撞击同时撞击了1个以上的球,对手+第一次同时撞击到的球中编号最大的分数

3 母球落袋并且撞击到了至少一个球,对手+第一次同时撞击到的球中编号最大的分数


在没有犯规的情况下,若目标球落袋,则我方的分数加上本轮落袋的球的分数和,并且下一轮依然是我方操作。如果我方犯规,或者是有球落袋但是目标球没有落袋,则对方加上落袋的球的分数和。所有操作结束后,求A:B的分数。


很考验细心的一道模拟,注意到,我方得分的情况只有首先只撞到了一个球,并且这个球是目标球,并且母球没有落袋,目标球落袋,这种情况下我方加分,并继续行动,否则一定是对方加分并且换手,其中对方加分的情况中有一点要考虑到,如果我方犯规了,对方会加上罚分,并且如果这次操作有球落袋了,对手会再加上落袋求的分数和。考虑到这些,写的时候细心点这题也就没什么大问题了...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
int pt[3];
int a[1010];
int b[1010];
int c[1010];
bool f[101000];
int n,m,k,x,y,z,p,q;
int x1,x2,x3,y1,y2,y3;
int main()
{
//    freopen("in.txt","r",stdin);
    while(~scanf("%d%d",&n,&m))
    {
        memset(f,false,sizeof f);
        memset(pt,0,sizeof pt);
        int tgt=20200;
        for (int i=1; i<=n; i++)
        scanf("%d",&a[i]);
        sort(a+1,a+1+n);
        tgt=a[1];
        int tgtnum=1;
        int side=0;
        int ad=side;
        int sum;
        for (int i=1; i<=m; i++)
        {
            f[0]=false;
            scanf("%d",&p);
            int minn=0;
            int minb=0;
            for (int i=1; i<=p; i++) scanf("%d",&b[i]),minn=max(minn,b[i]);
            if (p==1 && b[1]==tgt)
            {
                scanf("%d",&q);
                sum=0;
                minb=0;
                for (int i=1; i<=q; i++)
                {
                    scanf("%d",&c[i]),minb=max(minb,c[i]),sum+=c[i];
                    f[c[i]]=true;
                }
                if (f[0])
                {
                    pt[side^1]+=minn;
                    pt[side^1]+=sum;
                    side^=1;
                }
                else
                {
                    if (f[tgt]) pt[side]+=sum;
                    else pt[side^1]+=sum,side^=1;
                }
            }
            else
            {
                scanf("%d",&q);
                minb=0;
                sum=0;
                for (int i=1; i<=q; i++)
                scanf("%d",&c[i]),minb=max(minb,c[i]),sum+=c[i],f[c[i]]=true;

                if (p==0) pt[side^1]+=tgt;
                else if (!f[0]) pt[side^1]+=minn;

                if (f[0] && p>0) pt[side^1]+=minn;

                pt[side^1]+=sum;
                side^=1;
            }

            while(f[a[tgtnum]] && tgtnum<=n) tgtnum++;
            if (tgtnum>n) break;
            tgt=a[tgtnum];
        }
        cout<<pt[0]<<" : "<<pt[1]<<endl;
    }
    return 0;
}


你可能感兴趣的:(zoj 3757 Alice and Bob and Cue Sports 模拟)