题解:P9381 [THUPC 2023 决赛] 那些脑海里最珍贵的

· · 题解

感受

比起群星连结,这题没有很多易错的细节(除了没仔细读题),写完马上就过了大样例,然后几乎过了,而且调试时不用专门输出游戏进程,题目要求的的输出已经够用了。

感谢出题人的大样例。

题意

两队回合制对战。

保证合法!

思路

框架

我们需要维护的是两个队伍中的人以及他们的各种信息。

除了题中提到的信息,我还维护了人的编号,位置,队伍和存活状态,可以顺便写一下更新函数(用于判断 hp 是否合法)。 ::::info[结构体信息]

struct weapon
{
    string type;
    double atk;
};
struct people
{
    string race;
    int id,pos,team = -1;
    int alive,Lv,hp,maxhp,skillLv,passivesklLv;
    double atk,def,atkbuff = 1,defbuff = 1,skillbuff = 1;
    weapon wp;
    void update()
    {
        if(hp > maxhp) hp = maxhp;
        if(hp <= 0) hp = 0,alive = -1,passive(tim,0);
    }
}a[N],b[N];

:::: 之后的攻击和主动技能等函数就可以直接在人的结构体里实现。

问题拆解

我们要完成的事有:

  1. 输入基本信息;
  2. 找当前行动的人和目标;
  3. 扣血;
  4. 普通攻击;
  5. 特殊攻击;
  6. 被动技能;
  7. 主动技能;
  8. 判断胜利;
  9. 输出。

    实现

    输入

    使用 scanf 可以读入特定格式内容,不用专门处理科学计数法,当成普通实数即可。 ::::info[setup]

    void setup()
    {
    cin>>n>>m;
    for(int i = 1; i <= n; i ++)
    {
        cin>>a[i].race;
        a[i].id = i,a[i].alive = 1;
        a[i].pos = position[i],a[i].team = 0;
        scanf(" Lv=%d maxhp=%d atk=%lf def=%lf skillLv=%d passivesklLv=%d",&a[i].Lv,&a[i].maxhp,&a[i].atk,&a[i].def,&a[i].skillLv,&a[i].passivesklLv);
        a[i].hp = a[i].maxhp;
        cin>>a[i].wp.type;
        scanf(" weaponatk=%lf",&a[i].wp.atk);
    }
    for(int i = 1; i <= m; i ++)
    {
        cin>>b[i].race;
        b[i].id = i,b[i].alive = 1;
        b[i].pos = position[i],b[i].team = 1;
        scanf(" Lv=%d maxhp=%d atk=%lf def=%lf skillLv=%d passivesklLv=%d",&b[i].Lv,&b[i].maxhp,&b[i].atk,&b[i].def,&b[i].skillLv,&b[i].passivesklLv);
        b[i].hp = b[i].maxhp;
        cin>>b[i].wp.type;
        scanf(" weaponatk=%lf",&b[i].wp.atk);
    }
    }

    ::::

    找当前行动的人和目标

    注意要引用,不然会无法修改数组里的真实值。 ::::info[get_now,get_target]

    people &get_target(int tarteam,int tarid)
    {
    if(tarteam) return b[tarid];
    return a[tarid];
    }
    people &get_now(int t,int last)
    {
    if(t & 1)
    {
        for(int i = last + 1; i <= n; i ++)
            if(a[i].alive == 1) return a[i];
        for(int i = 1; i <= last; i ++)
            if(a[i].alive == 1) return a[i];
    }
    for(int i = last + 1; i <= m; i ++)
        if(b[i].alive == 1) return b[i];
    for(int i = 1; i <= last; i ++)
        if(b[i].alive == 1) return b[i];
    }
    int last[2];
    people &now = get_now(tim,last[tim & 1]);
    people &target = get_target(tim & 1,tar);
    last[tim & 1] = now.id;

    ::::

    扣血

    计算被扣血人的防御,可以直接写在结构体里,记得更新存活状态。 ::::info[hurt]

    void hurt(double strenth,int from)
    {
    if(alive != 1) return;
    double defense = def * defbuff;
    hp -= floor(strenth / defense);
    update();
    printf("%s %d took %d damage from %s %d -> %d/%d\n",teams[team].c_str(),id,int(floor(strenth / defense)),teams[team ^ 1].c_str(),from,hp,maxhp);
    }

    ::::

    普通攻击

    这里要实现的部分有点多,包括种族加成、方位加成。

直接调用目标的的扣血函数即可。 ::::info[basic]

double racebuff(people target)
{
    if(race == target.race) return 1;
    if(race == "Weak")
    {
        if(target.race == "Strong") return 1.1;
        return 0.9;
    }
    if(race == "Average")
    {
        if(target.race == "Weak") return 1.1;
        return 0.9;
    }
    if(target.race == "Weak") return 0.9;
    return 1.1;
}
double posbuff(int atkpos,int ddgpos)
{
    int x = (atkpos - ddgpos + 12) % 6;
    if(!x) return 1.25;
    if(x == 1 || x == 5) return 1;
    if(x == 3) return 0;
    return 0.75;
}
void basicattack(people &target,int atkpos,int ddgpos,double buff = 1)
{
    double attack = atk * wp.atk * atkbuff * skillbuff * racebuff(target) * posbuff(atkpos,ddgpos) * buff;
    target.hurt(attack,id);
}

::::

特殊攻击

对于「B」类型这里可以调用普通攻击,只要略加修改乘上一个加成即可。 对于另两种,我们要找到目标的左(西)右(东)两个人,类似于 get_now 函数。 ::::info[get_left,get_right]

people &get_left(people now)
{
    if(now.team)
    {
        int dis = 10,p = 0;
        for(int i = 1; i <= m; i ++)
            if(b[i].alive == 1 && b[i].pos < now.pos)
                if(now.pos - b[i].pos < dis) dis = now.pos - b[i].pos,p = i;
        return b[p];
    }
    int dis = 10,p = 0;
    for(int i = 1; i <= n; i ++)
        if(a[i].alive == 1 && a[i].pos < now.pos)
            if(now.pos - a[i].pos < dis) dis = now.pos - a[i].pos,p = i;
    return a[p];
}
people &get_right(people now)
{
    if(now.team)
    {
        int dis = 10,p = 0;
        for(int i = 1; i <= m; i ++)
            if(b[i].alive == 1 && b[i].pos > now.pos)
                if(b[i].pos - now.pos < dis) dis = b[i].pos - now.pos,p = i;
        return b[p];
    }
    int dis = 10,p = 0;
    for(int i = 1; i <= n; i ++)
        if(a[i].alive == 1 && a[i].pos > now.pos)
            if(a[i].pos - now.pos < dis) dis = a[i].pos - now.pos,p = i;
    return a[p];
}

:::: 由此,我们又可以用普通攻击实现剩余的部分了。 ::::info[special]

void specialattack(people &target,int atkpos,int ddgpos)
{
    if(wp.type == "B")
    {
        basicattack(target,atkpos,ddgpos,1.25);
    }
    else if(wp.type == "G")
    {
        int cnt = 1;
        people &left = get_left(target);
        if(left.alive == 1) cnt ++;
        people &right = get_right(target);
        if(right.alive == 1) cnt ++;
        double x = 1.35 / cnt;
        basicattack(target,atkpos,ddgpos,x);
        basicattack(left,atkpos,ddgpos,x);
        basicattack(right,atkpos,ddgpos,x);
    }
    else if(wp.type == "M")
    {
        basicattack(target,atkpos,ddgpos,1.15);
        people &left = get_left(target);
        basicattack(left,atkpos,ddgpos,0.23);
        people &right = get_right(target);
        basicattack(right,atkpos,ddgpos,0.23);
    }
}

::::

被动技能

::::warning[注意区分「Weak 种族」的被动技能于其他两者的区别]{open} 「Weak 种族」的被动技能只在己方回合执行,而其他两者会随着人的死亡而改变,需要重新计算。 :::: 我使用了一个参数来确定是否计算「Weak 种族」的被动技能。 ::::info[passive]

void passive(int tim,bool wk = 1)
{
    double we = 0,av = 0,st = 0;
    for(int i = 1; i <= n; i ++)
        if(a[i].alive == 1)
        {
            if(a[i].race == "Weak") we += weakpskill[a[i].passivesklLv];
            else if(a[i].race == "Average") av += averagepskill[a[i].passivesklLv];
            else if(a[i].race == "Strong") st += strongpskill[a[i].passivesklLv];
        }
    if(we > 0.05) we = 0.05;
    if(av > 0.1) av = 0.1;
    if(st > 0.1) st = 0.1;
    for(int i = 1; i <= n; i ++)
        if(a[i].alive == 1)
        {
            if(wk && (tim & 1) && we && a[i].hp != a[i].maxhp) printf("%s %d recovered +%d hp -> %d/%d\n",teams[0].c_str(),i,int(floor(we * a[i].maxhp)),min(a[i].hp + int(floor(we * a[i].maxhp)),a[i].maxhp),a[i].maxhp);
            if(wk && tim & 1) a[i].hp += floor(we * a[i].maxhp);
            a[i].defbuff = 1 + av;
            a[i].atkbuff = 1 + st;
            a[i].update();
        }
    we = 0,av = 0,st = 0;
    for(int i = 1; i <= m; i ++)
        if(b[i].alive == 1)
        {
            if(b[i].race == "Weak") we += weakpskill[b[i].passivesklLv];
            else if(b[i].race == "Average") av += averagepskill[b[i].passivesklLv];
            else if(b[i].race == "Strong") st += strongpskill[b[i].passivesklLv];
        }
    if(we > 0.05) we = 0.05;
    if(av > 0.1) av = 0.1;
    if(st > 0.1) st = 0.1;
    for(int i = 1; i <= m; i ++)
        if(b[i].alive == 1)
        {
            if(wk && !(tim & 1) && we && b[i].hp != b[i].maxhp) printf("%s %d recovered +%d hp -> %d/%d\n",teams[1].c_str(),i,int(floor(we * b[i].maxhp)),min(b[i].hp + int(floor(we * b[i].maxhp)),b[i].maxhp),b[i].maxhp);
            if(wk && !(tim & 1)) b[i].hp += floor(we * b[i].maxhp);
            b[i].defbuff = 1 + av;
            b[i].atkbuff = 1 + st;
            b[i].update();
        }
}

::::

主动技能

因为主动技能可能的目标是己方或敌方,因此我传了两个目标。 需要注意的是「Average 种族」的主动技能是在己方三个回合结束时更新,存在一个全局数组里(因为是覆盖而非叠加所以不用 vector),另外加一个标记数组确定是否受到技能影响。 ::::info[skill]

int hpdec[2][N][M],sta[2][N][M];
void skill(people &friendtarget,people &target)
{
    if(race == "Weak")
    {
        double x = friendtarget.maxhp * weakskill[skillLv];
        if(friendtarget.hp != friendtarget.maxhp) printf("%s %d recovered +%d hp -> %d/%d\n",teams[team].c_str(),friendtarget.id,int(floor(x)),min(int(floor(x + friendtarget.hp)),friendtarget.maxhp),friendtarget.maxhp);
        friendtarget.hp += floor(x);
        friendtarget.update();
    }
    else if(race == "Average")
    {
        double x = target.maxhp * averageskill[skillLv];
        hpdec[target.team][target.id][tim] = floor(x);
        hpdec[target.team][target.id][tim + 2] = floor(x);
        hpdec[target.team][target.id][tim + 4] = floor(x);
        sta[target.team][target.id][tim] = 1;
        sta[target.team][target.id][tim + 2] = 1;
        sta[target.team][target.id][tim + 4] = 1;
    }
    else if(race == "Strong")
    {
        double x = strongskill[skillLv];
        friendtarget.skillbuff = x;
    }
}
if(tim & 1)
{
    for(int i = 1; i <= m; i ++)
    {
        if(b[i].alive != 1 || !sta[1][i][tim]) continue;
        b[i].hp -= hpdec[1][i][tim];
        b[i].update();
        printf("%s %d took %d damage from skill -> %d/%d\n",teams[1].c_str(),i,hpdec[1][i][tim],b[i].hp,b[i].maxhp);
    }
}
else
{
    for(int i = 1; i <= n; i ++)
    {
        if(a[i].alive != 1 || !sta[0][i][tim]) continue;
        a[i].hp -= hpdec[0][i][tim];
        a[i].update();
        printf("%s %d took %d damage from skill -> %d/%d\n",teams[0].c_str(),i,hpdec[0][i][tim],a[i].hp,a[i].maxhp);
    }
}

::::

判断胜利

题目保证操作合法,因此只需在回合结束时判断即可。 ::::info[checkend]

void checkend()
{
    int k = 1;
    for(int i = 1; i <= n; k ++,i ++)
        if(a[i].alive == 1) break;
    if(k == n + 1) winner = "North";
    k = 1;
    for(int i = 1; i <= m; k ++,i ++)
        if(b[i].alive == 1) break;
    if(k == m + 1) winner = "South";
}

::::

输出

注意:

  1. 受伤无论有实际扣血均输出。
  2. 「Weak 种族」的主动、被动技能须判断是否有实际回血。
  3. 回合末的信息输出按照位置排列输出(不存在的人跳过,倒下的人也要输出 0)。
  4. 最后若没有队伍「胜利」则不输出。(其实这种错误只有我会犯

    整合后的代码

    ::::warning[大模拟要锻炼实现、调试能力,不建议看下面的丑陋代码]

    #include<bits/stdc++.h>
    using namespace std;
    const int printtim = 0,N = 20,M = 50010;
    int n,m,tim;
    string winner;
    string teams[] = {"South","North"};
    double weakskill[] = {0,0.1,0.12,0.15,0.17,0.20},averageskill[] = {0,0.06,0.07,0.08,0.09,0.1},strongskill[] = {0,2.1,2.17,2.24,2.32,2.4};
    double weakpskill[] = {0,0.013,0.016,0.019,0.022,0.025},averagepskill[] = {0,0.01,0.02,0.03,0.04,0.05},strongpskill[] = {0,0.01,0.02,0.03,0.04,0.05};
    int position[] = {0,3,4,2,5,1,6},ps[] = {0,5,3,1,2,4,6};
    struct people;
    people &get_left(people now);
    people &get_right(people now);
    void passive(int tim,bool wk);
    struct weapon
    {
    string type;
    double atk;
    };
    int hpdec[2][N][M],sta[2][N][M];
    struct people
    {
    string race;
    int id,pos,team = -1;
    int alive,Lv,hp,maxhp,skillLv,passivesklLv;
    double atk,def,atkbuff = 1,defbuff = 1,skillbuff = 1;
    weapon wp;
    void update()
    {
        if(hp > maxhp) hp = maxhp;
        if(hp <= 0) hp = 0,alive = -1,passive(tim,0);
    }
    double racebuff(people target)
    {
        if(race == target.race) return 1;
        if(race == "Weak")
        {
            if(target.race == "Strong") return 1.1;
            return 0.9;
        }
        if(race == "Average")
        {
            if(target.race == "Weak") return 1.1;
            return 0.9;
        }
        if(target.race == "Weak") return 0.9;
        return 1.1;
    }
    double posbuff(int atkpos,int ddgpos)
    {
        int x = (atkpos - ddgpos + 12) % 6;
        if(!x) return 1.25;
        if(x == 1 || x == 5) return 1;
        if(x == 3) return 0;
        return 0.75;
    }
    void hurt(double strenth,int from)
    {
        if(alive != 1) return;
        double defense = def * defbuff;
        hp -= floor(strenth / defense);
        update();
        printf("%s %d took %d damage from %s %d -> %d/%d\n",teams[team].c_str(),id,int(floor(strenth / defense)),teams[team ^ 1].c_str(),from,hp,maxhp);
    }
    void basicattack(people &target,int atkpos,int ddgpos,double buff = 1)
    {
        double attack = atk * wp.atk * atkbuff * skillbuff * racebuff(target) * posbuff(atkpos,ddgpos) * buff;
        target.hurt(attack,id);
    }
    void specialattack(people &target,int atkpos,int ddgpos)
    {
        if(wp.type == "B")
        {
            basicattack(target,atkpos,ddgpos,1.25);
        }
        else if(wp.type == "G")
        {
            int cnt = 1;
            people &left = get_left(target);
            if(left.alive == 1) cnt ++;
            people &right = get_right(target);
            if(right.alive == 1) cnt ++;
            double x = 1.35 / cnt;
            basicattack(target,atkpos,ddgpos,x);
            basicattack(left,atkpos,ddgpos,x);
            basicattack(right,atkpos,ddgpos,x);
        }
        else if(wp.type == "M")
        {
            basicattack(target,atkpos,ddgpos,1.15);
            people &left = get_left(target);
            basicattack(left,atkpos,ddgpos,0.23);
            people &right = get_right(target);
            basicattack(right,atkpos,ddgpos,0.23);
        }
    }
    void skill(people &friendtarget,people &target)
    {
        if(race == "Weak")
        {
            double x = friendtarget.maxhp * weakskill[skillLv];
            if(friendtarget.hp != friendtarget.maxhp) printf("%s %d recovered +%d hp -> %d/%d\n",teams[team].c_str(),friendtarget.id,int(floor(x)),min(int(floor(x + friendtarget.hp)),friendtarget.maxhp),friendtarget.maxhp);
            friendtarget.hp += floor(x);
            friendtarget.update();
        }
        else if(race == "Average")
        {
            double x = target.maxhp * averageskill[skillLv];
            hpdec[target.team][target.id][tim] = floor(x);
            hpdec[target.team][target.id][tim + 2] = floor(x);
            hpdec[target.team][target.id][tim + 4] = floor(x);
            sta[target.team][target.id][tim] = 1;
            sta[target.team][target.id][tim + 2] = 1;
            sta[target.team][target.id][tim + 4] = 1;
        }
        else if(race == "Strong")
        {
            double x = strongskill[skillLv];
            friendtarget.skillbuff = x;
        }
    }
    }a[N],b[N];
    people &get_left(people now)
    {
    if(now.team)
    {
        int dis = 10,p = 0;
        for(int i = 1; i <= m; i ++)
            if(b[i].alive == 1 && b[i].pos < now.pos)
                if(now.pos - b[i].pos < dis) dis = now.pos - b[i].pos,p = i;
        return b[p];
    }
    int dis = 10,p = 0;
    for(int i = 1; i <= n; i ++)
        if(a[i].alive == 1 && a[i].pos < now.pos)
            if(now.pos - a[i].pos < dis) dis = now.pos - a[i].pos,p = i;
    return a[p];
    }
    people &get_right(people now)
    {
    if(now.team)
    {
        int dis = 10,p = 0;
        for(int i = 1; i <= m; i ++)
            if(b[i].alive == 1 && b[i].pos > now.pos)
                if(b[i].pos - now.pos < dis) dis = b[i].pos - now.pos,p = i;
        return b[p];
    }
    int dis = 10,p = 0;
    for(int i = 1; i <= n; i ++)
        if(a[i].alive == 1 && a[i].pos > now.pos)
            if(a[i].pos - now.pos < dis) dis = a[i].pos - now.pos,p = i;
    return a[p];
    }
    void checkend()
    {
    int k = 1;
    for(int i = 1; i <= n; k ++,i ++)
        if(a[i].alive == 1) break;
    if(k == n + 1) winner = "North";
    k = 1;
    for(int i = 1; i <= m; k ++,i ++)
        if(b[i].alive == 1) break;
    if(k == m + 1) winner = "South";
    }
    people &get_target(int tarteam,int tarid)
    {
    if(tarteam) return b[tarid];
    return a[tarid];
    }
    people &get_now(int t,int last)
    {
    if(t & 1)
    {
        for(int i = last + 1; i <= n; i ++)
            if(a[i].alive == 1) return a[i];
        for(int i = 1; i <= last; i ++)
            if(a[i].alive == 1) return a[i];
    }
    for(int i = last + 1; i <= m; i ++)
        if(b[i].alive == 1) return b[i];
    for(int i = 1; i <= last; i ++)
        if(b[i].alive == 1) return b[i];
    }
    void setup()
    {
    cin>>n>>m;
    for(int i = 1; i <= n; i ++)
    {
        cin>>a[i].race;
        a[i].id = i,a[i].alive = 1;
        a[i].pos = position[i],a[i].team = 0;
        scanf(" Lv=%d maxhp=%d atk=%lf def=%lf skillLv=%d passivesklLv=%d",&a[i].Lv,&a[i].maxhp,&a[i].atk,&a[i].def,&a[i].skillLv,&a[i].passivesklLv);
        a[i].hp = a[i].maxhp;
        cin>>a[i].wp.type;
        scanf(" weaponatk=%lf",&a[i].wp.atk);
    }
    for(int i = 1; i <= m; i ++)
    {
        cin>>b[i].race;
        b[i].id = i,b[i].alive = 1;
        b[i].pos = position[i],b[i].team = 1;
        scanf(" Lv=%d maxhp=%d atk=%lf def=%lf skillLv=%d passivesklLv=%d",&b[i].Lv,&b[i].maxhp,&b[i].atk,&b[i].def,&b[i].skillLv,&b[i].passivesklLv);
        b[i].hp = b[i].maxhp;
        cin>>b[i].wp.type;
        scanf(" weaponatk=%lf",&b[i].wp.atk);
    }
    }
    void passive(int tim,bool wk = 1)
    {
    double we = 0,av = 0,st = 0;
    for(int i = 1; i <= n; i ++)
        if(a[i].alive == 1)
        {
            if(a[i].race == "Weak") we += weakpskill[a[i].passivesklLv];
            else if(a[i].race == "Average") av += averagepskill[a[i].passivesklLv];
            else if(a[i].race == "Strong") st += strongpskill[a[i].passivesklLv];
        }
    if(we > 0.05) we = 0.05;
    if(av > 0.1) av = 0.1;
    if(st > 0.1) st = 0.1;
    for(int i = 1; i <= n; i ++)
        if(a[i].alive == 1)
        {
            if(wk && (tim & 1) && we && a[i].hp != a[i].maxhp) printf("%s %d recovered +%d hp -> %d/%d\n",teams[0].c_str(),i,int(floor(we * a[i].maxhp)),min(a[i].hp + int(floor(we * a[i].maxhp)),a[i].maxhp),a[i].maxhp);
            if(wk && tim & 1) a[i].hp += floor(we * a[i].maxhp);
            a[i].defbuff = 1 + av;
            a[i].atkbuff = 1 + st;
            a[i].update();
        }
    we = 0,av = 0,st = 0;
    for(int i = 1; i <= m; i ++)
        if(b[i].alive == 1)
        {
            if(b[i].race == "Weak") we += weakpskill[b[i].passivesklLv];
            else if(b[i].race == "Average") av += averagepskill[b[i].passivesklLv];
            else if(b[i].race == "Strong") st += strongpskill[b[i].passivesklLv];
        }
    if(we > 0.05) we = 0.05;
    if(av > 0.1) av = 0.1;
    if(st > 0.1) st = 0.1;
    for(int i = 1; i <= m; i ++)
        if(b[i].alive == 1)
        {
            if(wk && !(tim & 1) && we && b[i].hp != b[i].maxhp) printf("%s %d recovered +%d hp -> %d/%d\n",teams[1].c_str(),i,int(floor(we * b[i].maxhp)),min(b[i].hp + int(floor(we * b[i].maxhp)),b[i].maxhp),b[i].maxhp);
            if(wk && !(tim & 1)) b[i].hp += floor(we * b[i].maxhp);
            b[i].defbuff = 1 + av;
            b[i].atkbuff = 1 + st;
            b[i].update();
        }
    }
    int last[2];
    int main()
    {
    //  freopen("2.in","r",stdin);
    //  freopen("2.out","w",stdout);
    setup();
    int t;
    cin>>t;
    for(tim = 1; tim <= t; tim ++)
    {
        if(printtim) cout<<tim<<" ";
        passive(tim);
        string s;
        int tar;
        cin>>s;
        scanf(" target=%d",&tar);
        people &now = get_now(tim,last[tim & 1]);
        people &target = get_target(tim & 1,tar);
        if(s == "Basicattack")
        {
            int atkpos,ddgpos;
            scanf(" atkpos=%d ddgpos=%d",&atkpos,&ddgpos);
            now.basicattack(target,atkpos,ddgpos);
            now.skillbuff = 1;
        }
        else if(s == "Specialattack")
        {
            int atkpos,ddgpos;
            scanf(" atkpos=%d ddgpos=%d",&atkpos,&ddgpos);
            now.specialattack(target,atkpos,ddgpos);
            now.skillbuff = 1;
        }
        else if(s == "Skill")
        {
            people &friendtarget = get_target((tim & 1) ^ 1,tar);
            printf("%s %d applied %s skill to ",teams[(tim & 1) ^ 1].c_str(),now.id,now.race.c_str());
            if(now.race == "Average") printf("%s %d\n",teams[tim & 1].c_str(),target.id);
            else printf("%s %d\n",teams[(tim & 1) ^ 1].c_str(),friendtarget.id);
            now.skill(friendtarget,target);
        }
        last[tim & 1] = now.id;
        if(tim & 1)
        {
            for(int i = 1; i <= m; i ++)
            {
                if(b[i].alive != 1 || !sta[1][i][tim]) continue;
                b[i].hp -= hpdec[1][i][tim];
                b[i].update();
                printf("%s %d took %d damage from skill -> %d/%d\n",teams[1].c_str(),i,hpdec[1][i][tim],b[i].hp,b[i].maxhp);
            }
        }
        else
        {
            for(int i = 1; i <= n; i ++)
            {
                if(a[i].alive != 1 || !sta[0][i][tim]) continue;
                a[i].hp -= hpdec[0][i][tim];
                a[i].update();
                printf("%s %d took %d damage from skill -> %d/%d\n",teams[0].c_str(),i,hpdec[0][i][tim],a[i].hp,a[i].maxhp);
            }
        }
        printf("%s: ",teams[1].c_str());
        for(int i = 1; i <= 6; i ++)
            if(~b[ps[i]].team) printf("%d/%d ",b[ps[i]].hp,b[ps[i]].maxhp);
        printf("\n%s: ",teams[0].c_str());
        for(int i = 1; i <= 6; i ++)
            if(~a[ps[i]].team) printf("%d/%d ",a[ps[i]].hp,a[ps[i]].maxhp);
        puts("\n");
        checkend();
    }
    if(winner != "") printf("Team %s won.\n",winner.c_str());//若没有队伍「胜利」则不输出
    return 0;
    }

    ::::