【牛客】B.最强的决斗者一切都是必然的!

2018年牛客多校算法寒假训练营练习比赛(第一场)

题目描述

  L 一直喜欢玩游戏王这款声控印卡游戏,使用一套连锁式削血卡组便可战无不胜。每当陷入危机即将败北之际,L便会高呼“最强的决斗者一切都是必然的!”,然后发动闪光印卡技能,直接翻盘,伤害不多不少,正好足够击败对手。
  发动闪光印卡技能后,L 抽取一张牌,然后微微一笑。接着L以一定顺序打出若干张牌,造成的伤害正好等于对方的生命值。每一张牌都有其发动速度以及效果。如果后发动的一张牌的发动速度不小于前一张牌,则后发动的那张牌会在前一张牌后进行连锁发动,这张牌的连锁数就是连锁发动的编号。不进行连锁发动的牌,连锁数为1。同一连锁中的牌,后发动的牌先生效。
  
如下图,5张牌的速度分别为(1,2,2,2,3),因此它们进行连锁发动。连锁数分别为(1,2,3,4,5),因为连锁中的牌,后发动的先生效,所以,生效顺序为(5,4,3,2,1)。

在这里插入图片描述
为简化问题,我们假设发动的牌的效果有如下几种:

  1. 对对方造成X点伤害
  2. 对对方造成这张牌的连锁数乘X点的伤害
  3. 同一连锁中的牌全部无效
  4. 连锁中的前一张牌无效

现在你知道L发动牌的效果、速度和顺序,求 L 能对对方造成多少伤害。

输入描述:
数据有多组,处理到文件结束
第一行一个整数 n ,代表L发动了多少张牌。
接下来n行,前两个数是两个整数 s 和 t ,代表牌的发动速度和效果(数字对应上述4类效果)。如果是第1、2类效果,则紧接着一个整数 x ,代表效果中的X的数值。

输出描述:
每组数据输出一行,一个整数,代表L能对对方造成的伤害。

示例
输入

9
1 1 300
2 2 400
2 3
2 2 500
1 1 1000
3 4
2 1 600
3 3
3 4

输出

2600

说明
  一共发动了9张牌,前四张为一次连锁发动,第四张先生效,连锁数为4,造成 4 ∗ 500 4*500 4500 伤害。接着第三张牌生效,使第一二张牌无效。第五六张牌为一次连锁发动,第六张牌先生效,使其连锁的前一张牌,即第五张牌无效。第七八九张牌为一次连锁发动,第九张牌先生效,使连锁中的前一张牌,即第八张牌无效。接着第七张牌生效,造成600伤害。总伤害为4*500+600=2600伤害。

备注:
对于100%的数据,1 <= n,x <= 1000; 1 <= s <= 3; 1 <= t <= 4。

扫描二维码关注公众号,回复: 15942068 查看本文章

题解

模拟:使用对象数组,记录连锁数数组、记录连锁次数、记录生效卡号数组

import java.util.Scanner;

class card {
    
    
    //牌的速度
    public int s;
    //牌的效果
    public int t;
    //造成的伤害
    public int x;
}

public class Solution {
    
    
    //声明对象数组
    static card[] c = new card[1002];
    //连锁,记录每一张卡从1开始,连锁的排序 1,2,3,4,1,2,1,2,3
    public static int[] liansuo = new int[1002];
    //生效,记录每一次生效卡在哪           4,6,9
    public static int[] shenxiao = new int[1002];

    public static void main(String[] args) {
    
    

        int n;
        Scanner in = new Scanner(System.in);

        while (in.hasNext()) {
    
    
            //n张牌
            n = in.nextInt();

            //处理输入,从1开始
            for (int i = 1; i <= n; i++) {
    
    
                //实例化对象数组
                c[i] = new card();
                c[i].s = in.nextInt();
                c[i].t = in.nextInt();
                if (c[i].t == 1 || c[i].t == 2) {
    
    
                    c[i].x = in.nextInt();
                }
            }

            liansuo[1] = 1;
            int ans = 1;//记录有多少组连锁,至少一组连锁
            //第二张牌开始
            for (int i = 2; i <= n; i++) {
    
    
                //后一张牌速度比前面大,可以连锁
                if (c[i].s >= c[i - 1].s) {
    
    
                    //连锁编号加加
                    liansuo[i] = liansuo[i - 1] + 1;
                }
                else {
    
    
                    //连锁置为1,上一次连锁结束,下一次
                    liansuo[i] = 1;
                    shenxiao[ans] = i - 1;//记录组里生效的那张牌
                    ans++;
                }
            }
            shenxiao[ans] = n;
            ans++;

            int sum = 0;
            //遍历连锁次数
            for (int i = 1; i < ans; i++) {
    
    
                //第4,6,9张牌先生效,shenxiao[i]是第i次连锁生效第一张的牌号,liansuo[shenxiao[i]]是第i次连锁第一张生效牌的连锁数
                for (int j = shenxiao[i]; j > shenxiao[i] - liansuo[shenxiao[i]]; j--) {
    
    
                    if (c[j].t == 1) {
    
    
                        sum += c[j].x;
                    }
                    if (c[j].t == 2) {
    
    
                        sum += c[j].x * liansuo[j];
                    }
                    if (c[j].t == 3) {
    
    
                        break;
                    }
                    if (c[j].t == 4) {
    
    
                        j--;
                    }
                }
            }
            System.out.println(sum);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_44033208/article/details/131850636
今日推荐