2016 计蒜之道 初赛 第五场

2016 计蒜之道 初赛 第五场

腾讯推出了一款新游戏:勇者的故事。在游戏里有一个勇者,要去挑战大魔王。大魔王有 nnn 支护卫队,第 iii 支护卫队里有 mim_im​i​​ 只恶魔。勇者和恶魔都有攻击力和防御力,当两个角色发生战斗时,若一方的防御力小于另一方的攻击力,则这一方会死亡(存在两边都死亡或两边都存活的情况)。勇者的攻击力是 111,恶魔们的防御力全都是 000。每当勇者 击杀 了一只恶魔并且勇者仍 存活,勇者的防御力会增加 111。当勇者与一支护卫队发生战斗时,勇者会依照护卫队的顺序从前往后依次与恶魔们发生战斗(这是因为恶魔们训练有素,他们总是排成一条竖线冲锋)。恶魔们一共会换防 qqq 次,对于第 iii 次换防 (xi,ai,yi,bi)(x_i,a_i,y_i,b_i)(x​i​​,a​i​​,y​i​​,b​i​​),第 xix_ix​i​​ 支护卫队的前 aia_ia​i​​ 只恶魔会与第 yiy_iy​i​​ 支护卫队的前 bib_ib​i​​ 只恶魔交换。

你的任务是在每次换防之后,计算出若此时勇者要击杀全部的护卫队恶魔并见到大魔王,至少需要多少点初始防御力。勇者可以决定先与哪支护卫队发生战斗,但必须击杀完一支护卫队才能挑战另一支。

输入格式

第一行输入一个正整数 n(n≥2)n(n \geq 2)n(n≥2),表示护卫队数量。

接下来输入 nnn 行,第 iii 行输入第一个整数 mi(mi≥0,∑imi≥1)m_i(m_i \geq 0,\sum_{i}m_i \geq 1)m​i​​(m​i​​≥0,∑​i​​m​i​​≥1),接着输入有 mim_im​i​​ 个空格分隔的整数 attacki,j(1≤attacki,j≤100000)attack_{i,j}(1 \leq attack_{i,j} \leq 100000)attack​i,j​​(1≤attack​i,j​​≤100000),表示第 iii 支护卫队按从前往后顺序,第 jjj 个恶魔的攻击力。

接下来一行输入一个整数 q(q≥1)q(q \geq 1)q(q≥1),表示换防次数。

接着输入 qqq 行,第 iii 行输入 444 个整数 xi,ai,yi,bi(xi≠yi;1≤x,y≤n;ai,bi≥0)x_i,a_i,y_i,b_i(x_i \neq y_i;1\leq x,y \leq n;a_i,b_i \geq 0)x​i​​,a​i​​,y​i​​,b​i​​(x​i​​≠y​i​​;1≤x,y≤n;a​i​​,b​i​​≥0),表示第 iii 次换防。

对于简单版本:n,mi,q≤8n,m_i,q \leq 8n,m​i​​,q≤8;∑imi≤64\sum_{i}m_i \leq 64∑​i​​m​i​​≤64;

对于中等版本:n,mi,q≤1000n,m_i,q \leq 1000n,m​i​​,q≤1000;∑imi≤1000\sum_{i}m_i \leq 1000∑​i​​m​i​​≤1000;

对于困难版本:n,mi,q≤100000n,m_i,q \leq 100000n,m​i​​,q≤100000;∑imi≤100000\sum_{i}m_i \leq 100000∑​i​​m​i​​≤100000。

输出格式

输出有 qqq 行,请在每次换防后,输出若此时勇者要 击杀 全部的护卫队恶魔并 存活,至少需要的初始防御力点数。
样例输入

2
5 2 5 1 5 6
4 5 6 7 8
3
1 3 2 2
1 4 2 0
1 0 2 5

样例输出

4
5
5

提示信息

第一次换防后,第一支护卫队变为 5,6,5,65,6,5,65,6,5,6,第二支护卫队变为 2,5,1,7,82,5,1,7,82,5,1,7,8。若先攻击第一队再攻击第二队,需要 555 点防御力。若先攻击第二队再攻击第一队,则只需要 444 点防御力。

第二次换防后,第一支护卫队没有恶魔了,第二支护卫队变为 5,6,5,6,2,5,1,7,85,6,5,6,2,5,1,7,85,6,5,6,2,5,1,7,8。

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

struct ListNode {
    int attack;
    ListNode *next;
    ListNode() {
        attack = 0;
        next = NULL;
    }
};

struct devilList {
    ListNode *head;
    int length;
    devilList() {
        head = NULL;
        length = 0;
    }
};

int getResultFromList(ListNode *head) {
    int cur = 0, min = 0;
    ListNode *head_t = head;
    while (head_t) {
        if (head_t->attack > cur) {
            min += head_t->attack - cur;
            cur = head_t->attack;
        }
        cur++;
        head_t = head_t->next;
    }
    return min;
}

int main() {
    int n;
    int i, j;
    int attack;
    ListNode *head_t, *node_t;
    //int _attack[1000];
    scanf("%d", &n);
    devilList *devil = (devilList *)malloc(sizeof(devilList) * n);
    memset(devil, 0, sizeof(devilList ) * n);
    for (i = 0; i < n; ++i) {
        scanf("%d", &(devil[i].length));
        for (j = 0; j < devil[i].length; ++j) {
            scanf("%d", &attack);
            if (!devil[i].head) {
                devil[i].head = (ListNode *)malloc(sizeof(ListNode));
                memset(devil[i].head, 0, sizeof(ListNode));
                devil[i].head->attack = attack;
                devil[i].head->next = NULL;
                head_t = devil[i].head;
            }
            else {
                node_t = (ListNode *)malloc(sizeof(ListNode));
                memset(node_t, 0, sizeof(ListNode));
                node_t->attack = attack;
                node_t->next = NULL;
                head_t->next = node_t;
                head_t = head_t->next;
            }
        }
    }

    int q;
    int *defX, *defA, *defY, *defB, *resQ;
    scanf("%d", &q);
    defX = (int *)malloc(sizeof(int) * q);
    defY = (int *)malloc(sizeof(int) * q);
    defA = (int *)malloc(sizeof(int) * q);
    defB = (int *)malloc(sizeof(int) * q);
    resQ = (int *)malloc(sizeof(int) * q);
    for (i = 0; i < q; ++i) {
        scanf("%d%d%d%d", &(defX[i]), &(defA[i]), &(defY[i]), &(defB[i]));
    }

    ListNode *tmp = NULL, *tmp2 = NULL;
    for (i = 0; i < q; ++i) {
        tmp = NULL;
        tmp2 = NULL;
        for (j = 0; j < defA[i]; ++j) {
            if (tmp) tmp = tmp->next;
            else tmp = devil[defX[i] - 1].head;
        }
        for (j = 0; j < defB[i]; ++j) {
            if (tmp2) tmp2 = tmp2->next;
            else tmp2 = devil[defY[i] - 1].head;
        }
        if (tmp && tmp2) {
            ListNode *tmp_next = tmp->next;
            tmp->next = tmp2->next;
            tmp2->next = tmp_next;
        }
        else {
            if (!tmp && !tmp2) {
                resQ[i] = 0;
                continue;
            }
            else {
                if (!tmp) {
                    tmp2->next = devil[defX[i] - 1].head;
                    devil[defX[i] - 1].head = NULL;
                }
                else {
                    tmp->next = devil[defY[i] - 1].head;
                    devil[defY[i] - 1].head = NULL;
                }
            }
        }
        ListNode *tmp_head = devil[defX[i] - 1].head;
        devil[defX[i] - 1].head = devil[defY[i] - 1].head;
        devil[defY[i] - 1].head = tmp_head;

        int min = 100000;
        for (j = 0; j < n; ++j) {
            int res = (devil[j].head) ? getResultFromList(devil[j].head) : min;
            min = (min < res) ? min : res;
        }
        resQ[i] = min;
    }
    for (i = 0; i < q; ++i) {
        printf("%d\n", resQ[i]);
    }
    return 0;
}

完美!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值