2024年睿抗机器人开发者大赛(RAICOM)CAIP-编程技能赛-本科组省赛_题解

本人分数:

10+15+17+1+30=73 九百多名次,省一

情况:

接近七千人比赛,前二十多分钟进不去,炸掉了,官方补时20min.

7.15比赛,ioi赛制,这么长时间出废物榜单,7.23出来错误榜单,漏了好几百人,群里所有人都在骂,7.24才出来第二遍的成绩。

官方群里的cy老师语录:

全是乐子

RC-u1 热҈热҈热҈  分数 10

热҈热҈热҈……最近热得打的字都出汗了!

幸好某连锁餐厅开启了气温大于等于 35 度即可获得一杯免费雪碧的活动。但不知为何,在每个星期四的时候,这个活动会暂停一天……

现在给定连续的若干天的气温情况以及给定的第一天是星期几,请你算出有多少天你可以喝到免费的雪碧,又有多少天是因为星期四而导致你喝不到雪碧的。

输入格式:

输入第一行是两个正整数 N, W (1≤N≤50,1≤W≤7),表示给定连续的 N 天,下面给定的第一天是星期 W(7 等于星期天)。

接下来的一行给出 N 个用一个空格隔开的、小于 60 的整数,第 i 个数表示第 i 天的温度。保证温度大于等于 -273 度。

输出格式:

输出两个数,第一个是你能喝到免费雪碧的天数,第二个是你本来能喝到免费雪碧、但因为是星期四而无法喝到的天数。

输入样例:

15 3
33 35 34 36 37 40 32 31 30 29 28 29 33 38 40

输出样例:

5 1

代码长度限制 16 KB

时间限制 400 ms

内存限制 64 MB

栈限制 8192 KB

满分:

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);

        int N = sc.nextInt();
        int W = sc.nextInt();
        int[] t = new int[N];
        for (int i = 0; i < N; i++) {
            t[i] = sc.nextInt();
           }
        int[] result = countSpritedays(N, W, t);

        System.out.println(result[0] + " " + result[1]);
            
}
     public static int[] countSpritedays(int N, int W, int[] t) {
      int free = 0;
      int thurs = 0;
        for (int i = 0; i < N; i++) {
            int temperature = t[i];
            int dayOfWeek = (W + i -1) % 7 + 1; // 计算当前星期几
             if (temperature >= 35) {
                 free++;
                 // System.out.println(dayOfWeek+ " " + i+ " " + temperature);
             }
             if (dayOfWeek == 4 && temperature >= 35) {
                 thurs++;
                 free--;
             }
         }
         return new int[]{free, thurs};
     }
}

RC-u2 谁进线下了?   分数 15

Xepa Legends 是一个第一人称射击类大逃杀(“吃鸡”)游戏,每轮游戏共有 20 支 3 人小队参加,最后获胜的队伍被称为“捍卫者”。

最近 Xepa Legends 举行了亚太地区南赛区的线上比赛,争夺 7 个前往德国曼海姆参加线下赛的资格,国内共有 14 支队伍参与到了其中。

因为比赛十分激烈,直到最后谁进了线下仍有巨大的疑问。

小 K 喜欢的国内知名战队 DreamTear 因其队内选手杀马特表现不佳,正好卡在出线分数前后,请你赶紧帮帮小 K,计算一下最后的分数情况,看看他喜欢的战队出线了没有吧!

Xepa Legends 的比赛共进行 N 场游戏,在每场游戏中,每支队伍在游戏中会获得一个排名和一个杀敌数(击败其他队伍玩家的数量),

一支队伍在一场游戏的得分为杀敌数+排名分,排名分由队伍当场的排名根据以下表格求得:

排名 分数

第一名 12 分

第二名 9 分

第三名 7 分

第四名 5 分

第五名 4 分

第六名至第七名 3 分

第八名至第十名 2 分

第十一名至第十五名 1 分

第十六名至第二十名 0 分

例如,

DreamTear 战队在第三场比赛获得了第三名、有 6 个杀敌数,那么他们将获得 7 + 6 = 13 分;

KV 战队在第二场比赛获得了第 19 名、有 1 个杀敌数,那么他们将获得 0 + 1 = 1 分;

SRN 战队在第四场比赛获得了第 1 名、有 9 个杀敌数,那么他们将获得 12 + 9 = 21 分。

注:本题与实际情况无关,所有比赛规则、队伍、队员名称均为虚构。

输入格式:

输入第一行是一个正整数 N (≤20),表示有 N 场比赛。

接下来有 N 部分输入,每部分是一场比赛的情况。

对每一场比赛,信息共分 20 行,第 i 行(i=1,⋯,20)给出的两个非负整数 p 和 k 表示第 i 支队伍在这场比赛里获得了第 p 名、杀敌数为 k。

数据保证所有给定的情况中,排名永远大于等于 1 且小于等于 20,杀敌数小于等于 57。

输出格式:

输出 20 行,按编号从小到大依次输出队伍的编号及该队全部游戏结束时的总分。

输入样例:

3
6 2
7 3
11 5
10 1
2 9
5 8
14 3
4 3
1 6
18 1
12 1
20 0
13 0
3 2
16 4
8 1
19 0
9 4
17 1
15 0
8 2
19 1
12 2
1 9
10 1
7 5
18 0
14 0
5 2
4 4
2 5
6 2
16 3
13 1
20 0
3 7
9 3
15 0
17 5
11 3
18 0
5 2
2 9
9 4
4 7
10 3
16 0
1 6
20 0
15 1
6 0
3 6
14 3
7 4
19 0
17 0
8 9
11 0
13 5
12 0

输出样例:

1 9
2 13
3 27
4 30
5 33
6 25
7 4
8 27
9 24
10 12
11 19
12 18
13 8
14 18
15 4
16 17
17 16
18 8
19 12
20 6

代码长度限制 16 KB

时间限制 400 ms

内存限制 64 MB

栈限制 8192 KB

满分:

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int[] arr = new int[20];
        int n = sc.nextInt();
        int[] res = new int[21];
        //忘记那个数组怎么新建了😭
        res[1] = 12;
        res[2] = 9;
        res[3] = 7;
        res[4] = 5;
        res[5] = 4;
        res[6] = 3;
        res[7] = 3;
        res[8] = 2;
        res[9] = 2;
        res[10] = 2;
        res[11] = 1;
        res[12] = 1;
        res[13] = 1;
        res[14] = 1;
        res[15] = 1;
        for(int i = 0;i<n*20;i++){
            int ming = sc.nextInt();
            int k = sc.nextInt();
            arr[(i%20)]=arr[(i%20)]+k+res[ming];
        }
        for(int i = 0;i<20;i++){
            System.out.println((i+1)+" "+arr[i]);
        }
    }
}

RC-u3 暖炉与水豚   分数 20

PapiCon(@PapilloteContet)出了许多有意思的谜题,其中有一道关于水豚的谜题是这样的:

GGwLLL_bwAA8cC4.jpeg

来源:x.com/PapilloteContet

在一个 N×M 的矩阵中有若干水豚以及暖炉,暖炉可以辐射以它自身为中心的 3×3 范围里的水豚,使其变得暖呼呼的。

谜题里存在一只冷的要命的水豚,你需要移动其中的一个暖炉,使所有水豚都变得暖呼呼的。

在往下读题前,如果你有兴趣的话,不妨思考一下如何解答这个谜题。(思考结果与题目无关,可跳过。)

这个谜题的关键在于,单纯从图中能看到的暖炉来说是无解的,但如果注意到,第 3 行第 6 列的水豚明明周围没有暖炉,却也处于暖呼呼的状态,

就能推测出来图中的那个对话框挡住了一个暖炉,只要移动这个暖炉就可以完成题目的要求。

现在我们将谜题一般化,对于给定的一个 N×M 的矩阵、对应的所有水豚状态、以及能看到的暖炉摆放情况,

已知最多只有一只水豚的状态不太对劲(周围没有暖炉却暖呼呼的),你需要推测有哪些格子可能藏了暖炉。一个空格可能藏了暖炉可以理解为:当前空格设置暖炉后整个矩阵的状态会从不合法变为合法。

输入格式:

输入第一行是两个正整数 N, M (1≤N,M≤1000),表示矩阵的大小。

接下来的 N 行,每行有 M 个字符,第 i 行的第 j 个字符表示矩阵中对应位置的状态,其中:

. 表示空格(或者说,看上去是空格的格子);

c 表示很冷的水豚;

w 表示暖呼呼的水豚;

m 表示暖炉。

输出格式:

输出若干行,每行两个正整数 r 和 c,表示第 r 行第 c 列有可能藏了一个暖炉,有多个可能时,先按 r 从小到大输出,r 相同时再按 c 从小到大输出。如果没有一个格子可能藏了暖炉, 则在一行中输出Too cold!。

行与列均从 1 开始编号。

输入样例:

6 8
wm....mw
.w..ww..
..wm.wwm
w.w....w
.m.c.m..
w.....w.

输出样例:

2 7
3 5
4 6
4 7

代码长度限制 16 KB

Java (javac)

时间限制 800 ms

内存限制 256 MB

其他编译器

时间限制 400 ms

内存限制 64 MB

栈限制 8192 KB

17分:

当时我特判了四个角,没踩到样例点,现在直接用除去首尾行列中间的点,可以过17/20分

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        char res[][] =new char[n][m];
        sc.nextLine();
        for(int i = 0;i<n;i++){
            res[i] = sc.nextLine().toCharArray();
        }
        //1、双层遍历找到 该冷但是不冷的(3*3没有m);
        for (int i = 1;i<n-1;i++){
            for (int j = 1; j < m-1; j++) {
                if(res[i][j]=='w'){
                    if(res[i-1][j-1]!='m'&&res[i-1][j+1]!='m'&&res[i-1][j]!='m'
                            &&res[i][j+1]!='m'&& res[i][j-1]!='m'
                            &&res[i+1][j-1]!='m'&&res[i+1][j+1]!='m'&&res[i+1][j]!='m'){
                        check(res,i-1,j-1);
                        check(res,i-1,j);
                        check(res,i-1,j+1);
                        check(res,i,j-1);
                        check(res,i,j+1);
                        check(res,i+1,j-1);
                        check(res,i+1,j);
                        check(res,i+1,j+1);

                        return;
                    }
                }
            }
        }
    }

    //查找该冷但是不冷的
    private static void check(char[][] res, int i, int j) {
        if (res[i][j] == '.') {
            //周围有c,说明肯定不是隐藏的
            if (checkc(res,i-1,j-1)){
                return;
            }
            if (checkc(res,i-1,j)){
                return;

            }if (checkc(res,i-1,j+1)){
                return;

            }if (checkc(res,i,j-1)){
                return;

            }if (checkc(res,i,j+1)){
                return;

            }if (checkc(res,i+1,j-1)){
                return;

            }if (checkc(res,i+1,j)){
                return;

            }if (checkc(res,i+1,j+1)){
                return;
            }
            //都没有c,就是隐藏的
            System.out.println((i+1)+" "+(j+1));
        }
    }

    private static boolean checkc(char[][] res, int i, int i1) {
        if (res[i][i1] == 'c') {
            return true;
        }
        return false;
    }
}

满分:

还有个Too cold! 的点值三分,最后我没来得及做,后面又去pta做了一次,在两个地方加上判断 就行。

我草,为啥首尾行列不用判断呀???我还想了下可以用填充不存在的周围行列的方式就不需要特殊判断了。

import java.util.Scanner;

public class Main {
    //判断是否有 疑似暖瓶的 点
    static boolean flag = false;

    public static void main(String[] args) {

        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        char res[][] =new char[n][m];
        sc.nextLine();
        for(int i = 0;i<n;i++){
            res[i] = sc.nextLine().toCharArray();
        }
        //1、双层遍历除开周围行列的 找到 该冷(3*3没有m)但是不冷的(本身是w);
        for (int i = 1;i<n-1;i++){
            for (int j = 1; j < m-1; j++) {
                if(res[i][j]=='w'){
                    if(res[i-1][j-1]!='m'&&res[i-1][j+1]!='m'&&res[i-1][j]!='m'
                            &&res[i][j+1]!='m'&& res[i][j-1]!='m'
                            &&res[i+1][j-1]!='m'&&res[i+1][j+1]!='m'&&res[i+1][j]!='m'){
                        check(res,i-1,j-1);
                        check(res,i-1,j);
                        check(res,i-1,j+1);
                        check(res,i,j-1);
                        check(res,i,j+1);
                        check(res,i+1,j-1);
                        check(res,i+1,j);
                        check(res,i+1,j+1);
                        if(flag == false){
                            System.out.println("Too cold!");
                        }
                        return;
                    }
                }
            }
        }
        System.out.println("Too cold!");
    }

    //查找该冷但是不冷的
    private static void check(char[][] res, int i, int j) {
        if (res[i][j] == '.') {
            //周围有c,说明肯定不是隐藏的m
            if (checkc(res,i-1,j-1)){
                return;
            }
            if (checkc(res,i-1,j)){
                return;

            }if (checkc(res,i-1,j+1)){
                return;

            }if (checkc(res,i,j-1)){
                return;

            }if (checkc(res,i,j+1)){
                return;

            }if (checkc(res,i+1,j-1)){
                return;

            }if (checkc(res,i+1,j)){
                return;

            }if (checkc(res,i+1,j+1)){
                return;
            }
            //都没有c,就是隐藏的
            System.out.println((i+1)+" "+(j+1));
            flag = true;
        }
    }

    private static boolean checkc(char[][] res, int i, int i1) {
        if (res[i][i1] == 'c') {
            return true;
        }
        return false;
    }
}

RC-u4 章鱼图的判断    分数 25

对于无向图 G=(V,E),我们将有且只有一个环的、大于 2 个顶点的无向连通图称之为章鱼图,因为其形状像是一个环(身体)带着若干个树(触手),故得名。

给定一个无向图,请你判断是不是只有一个章鱼子图存在。

输入格式:

输入第一行是一个正整数 T (1≤T≤5),表示数据的组数。

每组数据的第一行是两个正整数 N,M (1≤N,M≤10^5 ),表示给定的无向图有 N 个点,M 条边。

接下来的 M 行,每行给出一条边两个端点的顶点编号。注意:顶点编号从 1 开始,并且题目保证任何边不会重复给出,且没有自环。

输出格式:

对于每组数据,如果给定的图里只有一个章鱼子图,则在一行中输出 Yes 和章鱼子图环的大小(及环中顶点数),其间以 1 个空格分隔。

否则,则在一行中输出 No 和图中章鱼子图的个数,其间以 1 个空格分隔。

输入样例:

3
10 10
1 3
3 5
5 7
7 9
1 2
2 4
2 6
3 8
9 10
1 9
10 10
1 3
3 5
5 7
7 9
9 1
1 2
2 4
4 8
8 10
10 1
10 10
1 3
3 5
5 7
7 9
9 1
2 4
4 8
8 10
10 2
10 6

输出样例:

Yes 5
No 0
No 2

代码长度限制 16 KB

Java (javac)

时间限制 2500 ms

内存限制 512 MB

Python (python3)

时间限制 1400 ms

内存限制 512 MB

其他编译器

时间限制 1000 ms

内存限制 256 MB

栈限制 131072 KB

1分:

import java.util.Scanner;
public class Main {

    public static void main(String[] args) {
       Scanner sc = new Scanner(System.in);
        int[] arr = new int[10];
        int l = sc.nextInt();
        for(int i = 0;i<l;i++){

        System.out.println("No 0");
        }
    }
}

RC-u5 工作安排   分数 30

小 K 有 N 项工作等待完成,第 i 项工作需要花 t_i单位时间,必须在 d_i时刻或之前完成,报酬为 p_i 。

假设小 K 工作时刻从 0 开始,且同一时刻只能做一项工作、工作一旦开始则不可中断或切换至其他工作,

请你帮小 K 规划一下如何选择合适的工作,使小 K 可以获得最多的报酬。

输入格式:

输入第一行是一个正整数 T (≤5),表示数据的组数。

接下来有 T 组数据,每组数据第一行是一个正整数 N (≤5000),表示待完成工作的数量。

接下来的 N 行,每行三个非负整数 t_i 、d_i 、p_i (均 ≤5000;1≤i≤N),表示第 i 项工作需要花费的时间、截止时间以及报酬。

输出格式:

对于每组数据,输出小 K 能获得最多的报酬是多少。

输入样例:

3
5
1 2 50
3 3 100
1 5 1
3 2 5000
4 5 30
5
1 2 50
3 3 20
1 5 1
3 2 5000
4 5 30
5
1 2 50
3 3 100
1 5 1
3 2 5000
5 5 800

输出样例:

101
80
800

代码长度限制 16 KB

Java (javac)

时间限制 1000 ms

内存限制 256 MB

其他编译器

时间限制 400 ms

内存限制 64 MB

栈限制 8192 KB

满分:

import java.util.Arrays;
import java.util.Comparator;
import java.util.Scanner;
import java.util.StringTokenizer;

public class Main {

    static class j {
        int t; // 花费时间
        int d; // 截止时间
        int p; // 报酬

        j(int t, int d, int p) {
            this.t = t;
            this.d = d;
            this.p = p;
        }
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int T = sc.nextInt();

        for (int t = 0; t < T; t++) {
            int n = sc.nextInt();
            j[] jobs = new j[n];

            for (int i = 0; i < n; i++) {
                int tt = sc.nextInt();
                int d = sc.nextInt();
                int p = sc.nextInt();
                jobs[i] = new Joba(tt, d, p);
            }

            Arrays.sort(jobs, Comparator.comparingInt(job -> job.d));

            int[] dp = new int[9999];

            for (int i = 0; i < n; i++) {
                int ti = jobs[i].t;
                int di = jobs[i].d;
                int pi = jobs[i].p;

                // 逆序更新dp数组,确保每个工作只被考虑一次
                for (int j = di; j >= ti; j--) {
                    if (j >= ti) {
                        dp[j] = Math.max(dp[j], dp[j - ti] + pi);
                    }
                }
            }

            // 最大值
            int maxProfit = 0;
            for (int j = 0; j <= 5000; j++) {
                maxProfit = Math.max(maxProfit, dp[j]);
            }

            System.out.println(maxProfit);
        }
    }

}

  • 90
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 17
    评论
评论 17
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

软工菜鸡

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值