zoj 3757 Alice and Bob and Cue Sports 模拟

来源:互联网 发布:全志a20 linux移植 编辑:程序博客网 时间:2024/06/08 04:11

    两个人打台球,初始状态为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;}


0 0