1 条题解

  • 0
    @ 2025-8-24 22:47:51

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 向晚大魔王
    -

    搬运于2025-08-24 22:47:51,当前版本为作者最后更新于2023-06-15 22:40:49,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    小 E 说要有题解,于是就有了题解。

    按照题意模拟即可。

    代码中始终让 aa 代表当前行动的一方。

    一些需要注意的细节:

    • 死人之后被动增益需要重算。
    • 不造成伤害的攻击也要输出。
    • 不造成生命值增加的回复不能输出。
    • 被动回血在回合开始时发动。
    • 被动扣血在回合结束时发动。
    • 注意浮点数精度。

    和考场代码编辑距离不超过 20。

    大样例不判主动技能回血时是否形成了实际的数值提升也能过,警钟敲烂。

    #include <bits/stdc++.h>
    #define int long long
    #define double long double
    int read()
    {
        int x=0,f=1,c=getchar();
        while(c<48||c>57){if(c=='-')f=-1;c=getchar();}
        while(c>47&&c<58)x=x*10+c-48,c=getchar();
        return x*f; 
    }
    using namespace std;
    struct node
    {
        char type[23];
        int lv,maxhp;
        int hp;
        double atk,def;
        int slv,pslv;
        char wtype[23];
        double watk;
        double ex_skill=1;
        double cut;
        int remainround;
        void in()
        {
            scanf("%s Lv=%lld maxhp=%lld atk=%Lf def=%Lf skillLv=%lld passivesklLv=%lld %s weaponatk=%Lf",
            type,&lv,&maxhp,&atk,&def,&slv,&pslv,wtype,&watk);
            // printf("%s %lld %lld %Lf %Lf %lld %lld %s %Lf\n",type,lv,maxhp,atk,def,slv,pslv,wtype,watk);
            hp=maxhp;
        }
    }a[13],b[13];
    const int p[]={0,5,3,1,2,4,6,0};
    const int ip[]={0,3,4,2,5,1,6,0};
    int n=read(),m=read();
    double ex_type(node x,node y)
    {
        char A=x.type[0],B=y.type[0];
        int va=0,vb=0;
        if(A=='A') va=1;
        if(A=='S') va=2;
        if(B=='A') vb=1;
        if(B=='S') vb=2;
        int s=(va+3-vb)%3;
        if(s==0) return 1;
        else if(s==2) return 0.9;
        else return 1.1;
    }
    double ex_pos(int ap,int dp)
    {
        int g=(ap+6-dp)%6;
        if(g==0) return 1.25;
        else if(g==1||g==5) return 1;
        else if(g==2||g==4) return 0.75;
        else return 0;
    }
    const double ew_table[]={0,0.013,0.016,0.019,0.022,0.025};
    const double ea_table[]={0,0.01,0.02,0.03,0.04,0.05};
    const double es_table[]={0,0.01,0.02,0.03,0.04,0.05};
    const double sw_table[]={0,0.1,0.12,0.15,0.17,0.2};
    const double sa_table[]={0,0.06,0.07,0.08,0.09,0.1};
    const double ss_table[]={0,2.1,2.17,2.24,2.32,2.4};
    double Aexatk=1,Aexdef=1,Bexatk=1,Bexdef=1;
    double heal;
    void recalc()
    {
        heal=0;
            Aexatk=Aexdef=Bexatk=Bexdef=1;
            for(int i=1; i<=n; ++i) if(a[i].hp>0)
            {
                if(a[i].type[0]=='W') heal+=ew_table[a[i].pslv];
                else if(a[i].type[0]=='A') Aexdef+=ea_table[a[i].pslv];
                else Aexatk+=es_table[a[i].pslv];
            }
            for(int i=1; i<=m; ++i) if(b[i].hp>0)
            {
                if(b[i].type[0]=='W');
                else if(b[i].type[0]=='A') Bexdef+=ea_table[b[i].pslv];
                else Bexatk+=es_table[b[i].pslv];
            }
            heal=min(heal,0.05L),Aexatk=min(Aexatk,1.1L),Aexdef=min(Aexdef,1.1L);
            Bexatk=min(Bexatk,1.1L),Bexdef=min(Bexdef,1.1L);
    }
    const double eps=1e-9;
    signed main()
    {
        for(int i=1; i<=n; ++i) a[i].in();
        for(int i=1; i<=m; ++i) b[i].in();
        int lsta=0,lstb=0;
        int T=read();
        char player[]="South";
        char rival[]="North";
        
        for(int I=1; I<=T; ++I)
        {
            recalc();
            // cout<<heal<<endl;
            for(int i=1; i<=n; ++i) if(a[i].hp>0&&a[i].hp<a[i].maxhp)
            {
                int qwq=a[i].maxhp*heal+eps;
                a[i].hp=min(a[i].maxhp,a[i].hp+qwq);
                if(qwq)
                printf("%s %lld recovered +%lld hp -> %lld/%lld\n",player,i,qwq,a[i].hp,a[i].maxhp);
                
            }
            char str[103];
            scanf("%s",str);
            int tgt,ap,dp,cur=-1;
            for(int i=lsta+1; i<=n; ++i) if(a[i].hp>0){cur=i;break;}
            if(cur==-1)for(int i=1; i<=n; ++i) if(a[i].hp>0){cur=i;break;}
            lsta=cur;
            // for(int i:{5,3,1,2,4,6}) if((i<=m)&&b[i].hp>0) printf("%lld ",i);
            // puts("");
            if(str[1]=='a') //basic
            {
                scanf(" target=%lld atkpos=%lld ddgpos=%lld\n",&tgt,&ap,&dp);
                int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp)
                *a[cur].ex_skill/b[tgt].def/Bexdef+eps;
                b[tgt].hp=max(0ll,b[tgt].hp-dmg);
                printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n",
                rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp);
                a[cur].ex_skill=1;
            }
            else if(str[1]=='p') //special
            {
                scanf(" target=%lld atkpos=%lld ddgpos=%lld\n",&tgt,&ap,&dp);
                // double dmg=
                if(a[cur].wtype[0]=='B')
                {
                    int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp)
                    *a[cur].ex_skill/b[tgt].def/Bexdef*1.25+eps;
                    b[tgt].hp=max(0ll,b[tgt].hp-dmg);
                    printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n",
                    rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp);
                }
                else if(a[cur].wtype[0]=='G')
                {
                    int left=ip[tgt]-1,right=ip[tgt]+1;
                    while(left>=1&&(p[left]>m||b[p[left]].hp<=0)) --left;
                    while(right<=6&&(p[right]>m||b[p[right]].hp<=0)) ++right;
                    if(right>6) right=0;
                    left=p[left],right=p[right];
                    // printf("%d %d\n",left,right);
                    int z=(left>0)+(right>0)+1;
                                int dmg=a[cur].atk*a[cur].watk
                                *Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp)
                                *a[cur].ex_skill*1.35
                                /b[tgt].def/Bexdef/z+eps;
                                b[tgt].hp=max(0ll,b[tgt].hp-dmg);
                                printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n",
                                rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp);
                    tgt=left;
                    if(tgt)
                    {
                        recalc();
                        int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp)
                        *a[cur].ex_skill*1.35/b[tgt].def/Bexdef/z+eps;
                        b[tgt].hp=max(0ll,b[tgt].hp-dmg);
                        printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n",
                        rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp);
                    }
                    tgt=right;
                    if(tgt)
                    {
                        recalc();
                        int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp)
                        *a[cur].ex_skill*1.35/b[tgt].def/Bexdef/z+eps;
                        b[tgt].hp=max(0ll,b[tgt].hp-dmg);
                        printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n",
                        rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp);
                    }
                }
                else
                {
                    int left=ip[tgt]-1,right=ip[tgt]+1;
                    while(left>=1&&(p[left]>m||b[p[left]].hp<=0)) --left;
                    while(right<=6&&(p[right]>m||b[p[right]].hp<=0)) ++right;
                    if(right>6) right=0;
                    left=p[left],right=p[right];
                                int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp)
                                *a[cur].ex_skill*1.15/b[tgt].def/Bexdef+eps;
                                b[tgt].hp=max(0ll,b[tgt].hp-dmg);
                                printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n",
                                rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp);
                    tgt=left;
                    if(tgt)
                    {
                        recalc();
                        int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp)
                        *a[cur].ex_skill*0.23/b[tgt].def/Bexdef+eps;
                        b[tgt].hp=max(0ll,b[tgt].hp-dmg);
                        printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n",
                        rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp);
                    }
                    tgt=right;
                    if(tgt)
                    {
                        recalc();
                        int dmg=a[cur].atk*a[cur].watk*Aexatk*ex_type(a[cur],b[tgt])*ex_pos(ap,dp)
                        *a[cur].ex_skill*0.23/b[tgt].def/Bexdef+eps;
                        b[tgt].hp=max(0ll,b[tgt].hp-dmg);
                        printf("%s %lld took %lld damage from %s %lld -> %lld/%lld\n",
                        rival,tgt,dmg,player,cur,b[tgt].hp,b[tgt].maxhp);
                    }
                }
                a[cur].ex_skill=1;
            }
            else //skill
            {
                scanf(" target=%lld\n",&tgt);
                if(a[cur].slv!=0){ 
                if(a[cur].type[0]=='W')
                {
                    printf("%s %lld applied %s skill to %s %lld\n",player,cur,a[cur].type,player,tgt);
                    int qwq=a[tgt].maxhp*sw_table[a[cur].slv]+eps;
                    bool ok=(a[tgt].hp==a[tgt].maxhp);
                    a[tgt].hp=min(a[tgt].maxhp,a[tgt].hp+qwq);
                    if(qwq&&ok==0)
                    printf("%s %lld recovered +%lld hp -> %lld/%lld\n",player,tgt,qwq,a[tgt].hp,a[tgt].maxhp);
                }
                else if(a[cur].type[0]=='A')
                {
                    printf("%s %lld applied %s skill to %s %lld\n",player,cur,a[cur].type,rival,tgt);
                    b[tgt].cut=sa_table[a[cur].slv];
                    b[tgt].remainround=3;
                }
                else
                {
                    printf("%s %lld applied %s skill to %s %lld\n",player,cur,a[cur].type,player,tgt);
                    a[tgt].ex_skill=ss_table[a[cur].slv];
                }}
            }
            for(int i=1; i<=m; ++i)
            {
                if(b[i].remainround>0&&b[i].hp>0)
                {
                    int qwq=b[i].cut*b[i].maxhp+eps;
                    --b[i].remainround,
                    b[i].hp=max(b[i].hp-qwq,0ll);
                    printf("%s %lld took %lld damage from skill -> %lld/%lld\n",rival,i,qwq,b[i].hp,b[i].maxhp);
                }
            }
            if(rival[0]=='S')
            {
                printf("North: ");
                for(int i:{5,3,1,2,4,6})
                    if(i<=n) printf("%lld/%lld ",a[i].hp,a[i].maxhp);
                puts("");printf("South: ");
                for(int i:{5,3,1,2,4,6})
                    if(i<=m) printf("%lld/%lld ",b[i].hp,b[i].maxhp);
            }
            else
            {
                printf("North: ");
                for(int i:{5,3,1,2,4,6})
                    if(i<=m) printf("%lld/%lld ",b[i].hp,b[i].maxhp);
                puts("");printf("South: ");
                for(int i:{5,3,1,2,4,6})
                    if(i<=n) printf("%lld/%lld ",a[i].hp,a[i].maxhp);
            }
            puts("");puts("");
            swap(a,b),swap(lsta,lstb),swap(n,m);
            swap(rival,player);
        }
        bool win=1;
        for(int i=1; i<=n; ++i) win&=(a[i].hp==0);
        if(win) printf("Team %s won.",rival);
        return 0;
    }
    
    • 1

    [THUPC 2023 决赛] 那些脑海里最珍贵的

    信息

    ID
    8812
    时间
    1000ms
    内存
    512MiB
    难度
    6
    标签
    递交数
    0
    已通过
    0
    上传者