题目 3158: 蓝桥杯2023年第十四届省赛真题-三国游戏(贪心)

2023-04-28 17:06:01 来源:博客园


【资料图】

题目描述

小蓝正在玩一款游戏。游戏中魏蜀吴三个国家各自拥有一定数量的士兵X, Y, Z (一开始可以认为都为 0 )。游戏有 n 个可能会发生的事件,每个事件之间相互独立且最多只会发生一次,当第 i 个事件发生时会分别让 X, Y, Z 增加Ai , Bi ,Ci 。当游戏结束时 (所有事件的发生与否已经确定),如果 X, Y, Z 的其中一个大于另外两个之和,我们认为其获胜。例如,当 X > Y + Z 时,我们认为魏国获胜。小蓝想知道游戏结束时如果有其中一个国家获胜,最多发生了多少个事件?如果不存在任何能让某国获胜的情况,请输出 −1 。

输入格式

输入的第一行包含一个整数 n 。第二行包含 n 个整数表示 Ai,相邻整数之间使用一个空格分隔。第三行包含 n 个整数表示 Bi,相邻整数之间使用一个空格分隔。第四行包含 n 个整数表示 Ci,相邻整数之间使用一个空格分隔。

输出格式

输出一行包含一个整数表示答案。样例输入31 2 22 3 21 0 7样例输出2

解答

1.解题思路是,使用贪心思想选出三个国家各自获胜的最大事件数,取其最大作为答案;那么如何算出一个国家士兵应该经历哪些事件并满足大于另外两国呢,同样使用贪心算法2.我们使用一个类来存储一个事件,这个事件有abc三个属性,分别对应题目对三个国家兵力的提升

static class node {        long a, b, c;        public node(long a, long b, long c) {            this.a = a;            this.b = b;            this.c = c;        }    }

那么我们输入数据时需要注意一点,它的每一行都是对一个国家的影响,也就是对于事件i,输入的第一行数据是事件i的a,第二行数据才是事件i的b

node[] events = new node[n];    for (int i = 0; i < n; i++) events[i] = new node(sc.nextInt(), 0, 0);     for (int i = 0; i < n; i++) events[i].b = sc.nextInt();    for (int i = 0; i < n; i++) events[i].c = sc.nextInt();

3.我们对事件进行排序,排序规则根据我们的需求而定,我们需要得出每个国家获胜的事件数,就把事件排序为对那个国家提升的兵力最多的事件最靠前比如1 2 22 3 21 0 7事件i1对第一个国家提升量为-2,而i2提升量为-1,i3提升量为-7,则排序为i2i1i3事件i1对第二个国家提升量为0,而i2提升量为1,i3提升量为-7,则排序为i2i1i3事件i1对第三个国家提升量为-2,而i2提升量为-5,i3提升量为3,则排序为i3i1i2

Arrays.sort(events, (o1, o2) -> o2.a - o2.b - o2.c + o1.b + o1.c - o1.a > 0 ? 1 : -1);  Arrays.sort(events, (o1, o2) -> o2.b - o2.a - o2.c + o1.a + o1.c - o1.b > 0 ? 1 : -1);  Arrays.sort(events, (o1, o2) -> o2.c - o2.a - o2.b + o1.a + o1.b - o1.c > 0 ? 1 : -1);

排序完之后使用排序后的顺序算出对应国家在最大优势的情况下可以经过几个事件并满足兵力大于其他两国

Arrays.sort(events, (o1, o2) -> o2.a - o2.b - o2.c + o1.b + o1.c - o1.a > 0 ? 1 : -1);  ans = Math.max(ans, f(events, 0));  Arrays.sort(events, (o1, o2) -> o2.b - o2.a - o2.c + o1.a + o1.c - o1.b > 0 ? 1 : -1);  ans = Math.max(ans, f(events, 1));  Arrays.sort(events, (o1, o2) -> o2.c - o2.a - o2.b + o1.a + o1.b - o1.c > 0 ? 1 : -1);  ans = Math.max(ans, f(events, 2));

这里使用一个数字标记当前优势国,而且如果你不能在第一个事件就大于其他两国,那么后面就更不可能了,所以不满足a>b+c时就直接break并返回事件数

private static long f(node[] events, int cur) {        long a = 0, b = 0, c = 0;        long res = 0;        for (int i = 0; i < events.length; i++) {            a += events[i].a;            b += events[i].b;            c += events[i].c;            if (cur == 0) {                if (a > b + c) {                    res = i + 1;                } else {                    break;                }            } else if (cur == 1) {                if (b > a + c) {                    res = i + 1;                } else {                    break;                }            } else {                if (c > b + a) {                    res = i + 1;                } else {                    break;                }            }        }        return res;    }

4.最后打印答案,如果事件数为0,说明没有国家能够满足a>b+c的条件打印-1即可

System.out.println(ans == 0 ? -1 : ans);

完整代码

import java.util.Arrays;import java.util.Scanner;public class Main {    public static void main(String[] args) {        Scanner sc = new Scanner(System.in);        int n = sc.nextInt();        long ans = 0;        node[] events = new node[n];        for (int i = 0; i < n; i++) events[i] = new node(sc.nextInt(), 0, 0);        for (int i = 0; i < n; i++) events[i].b = sc.nextInt();        for (int i = 0; i < n; i++) events[i].c = sc.nextInt();        Arrays.sort(events, (o1, o2) -> o2.a - o2.b - o2.c + o1.b + o1.c - o1.a > 0 ? 1 : -1);        ans = Math.max(ans, f(events, 0));        Arrays.sort(events, (o1, o2) -> o2.b - o2.a - o2.c + o1.a + o1.c - o1.b > 0 ? 1 : -1);        ans = Math.max(ans, f(events, 1));        Arrays.sort(events, (o1, o2) -> o2.c - o2.a - o2.b + o1.a + o1.b - o1.c > 0 ? 1 : -1);        ans = Math.max(ans, f(events, 2));        System.out.println(ans == 0 ? -1 : ans);    }    private static long f(node[] events, int cur) {        long a = 0, b = 0, c = 0;        long res = 0;        for (int i = 0; i < events.length; i++) {            a += events[i].a;            b += events[i].b;            c += events[i].c;            if (cur == 0) {                if (a > b + c) {                    res = i + 1;                } else {                    break;                }            } else if (cur == 1) {                if (b > a + c) {                    res = i + 1;                } else {                    break;                }            } else {                if (c > b + a) {                    res = i + 1;                } else {                    break;                }            }        }        return res;    }    static class node {        long a, b, c;        public node(long a, long b, long c) {            this.a = a;            this.b = b;            this.c = c;        }    }}

标签

郴州安仁文旅项目集中开工 总投资1000万元

3月16日,安仁县举行文旅项目集中开工活动,县委书记王洪灿在开工仪式上宣布:湘南起义旧址群——朱毛井...

2022-03-20 15:40:46

2022年郴州计划重点推进文旅项目101个 总投资354亿元

3月16日,我市举行全市文旅项目和城市大提质大融城项目集中开工仪式,市委书记吴巨培宣布项目开工。郴州...

2022-03-20 15:39:41

宿州泗县深入推进文旅融合发展 擦亮城市品牌

近年来,泗县以争创安徽省文化旅游名县为目标,深入推进文旅融合发展,努力擦亮水韵泗州 运河名城城市...

2022-03-20 15:38:59

汽车零部件产业“领头羊” 锦州力争一季度“开门红”

3月16日,记者从锦州汽车零部件产业的领头羊——锦州万得集团获悉,今年前两个月,企业订单充足,正铆足...

2022-03-20 15:37:41

油价或有望冲击“九元”大关 宁波新能源汽车市场如何

新一轮国内成品油调价窗口于3月17日24时开启,油价或有望冲击九元大关。前一天晚上11点,鄞州区不少加油...

2022-03-20 15:34:38

从水塘到“云”端 全国最大高邮鸭养殖基地实现智慧养殖

随着新一代数字技术的蓬勃发展,以新兴技术推动现代化新农村建设正成为助力乡村振兴的重要手段。1个人能...

2022-03-20 15:33:17

淡季不忘引流 京郊民宿市场有望迎来回暖

旅游淡季中的京郊民宿有望成为市场中最先复苏的板块。3月17日,北京商报记者调查发现,虽然正值旅游淡季...

2022-03-20 15:32:01

镇江乡村一二三产业融合发展 闯出“镇江之路”

从烹饪江鲜河豚的个体小饭店到规模化的江岛乡村旅游产业集群,从白兔草莓丁庄葡萄的单个农户种植到茅山...

2022-03-20 15:31:11

总投资30亿元 盐城东台8个重大产业项目相继开工

总投资30亿元的精密电子元器件项目、同益电子项目,总投资10亿元的金利美精密组件项目、天永智能设备项...

2022-03-20 15:30:13

去年南京规上信息软件业企业实现营收7577.28亿元 同比增长10.3%

市统计局最新统计数据显示,2021年,我市规模以上信息软件业企业共1662家,较上年同期增加321家,实现营...

2022-03-20 15:28:57
x 广告
x 广告

Copyright  2015-2022 亚太粮油网版权所有  备案号:沪ICP备2020036824号-11   联系邮箱: 562 66 29@qq.com