厦门大学嘉庚学院:第九届编程大赛预选赛试题及其解析

厦门大学嘉庚学院第九届编程大赛预选赛试题及其解析,快来试试吧!

厦门大学嘉庚学院:第九届编程大赛预选赛试题及其解析

例题一:YYDS

题意:

按照字典序排序输入的字符串,后面加上 YYDS! 后输出

题解:

使用sort排序 字符串,sort默认为字典序

使用set容器 ,默认对容器内元素采用字典序排序

打卡题,这里就不放代码了


例题二:TCL和TQL

题意:

如果有一个60以下则输出“TCL”,如果所有课程的成绩都大于等于85,且平均分大于等于90,则输出"TQL"

题解:

可以使用printf格式化输出 ,其他的直接看代码吧

代码:

    for(int i=1;i<=n;i++){
        int m,sum=0,flag=1,a;
        cin>>m;
        for(int j=0;j>a;//输入成绩
            if(flag==-1)continue;//若已经存在60以下科目则不继续判断
            if(a<60)flag=-1;//存在60以下科目,TCL
            else if(a<85)flag=0;//存在85以下科目,无法成为优秀学生
            else sum+=a;//计算当前总分
        }
        if(sum<90*m&&flag==1)flag=0;//平均分小于90,无法成为优秀学生
        if(flag==-1)printf("No.%d TCL
",i);
        else if(flag==1)printf("No.%d TQL
",i);
    }

例题三:市质检的分数 [前缀和]

题意:

求区间[a,b]内的平均分

题解:

这道题是经典的前缀和题目,所以首先介绍一下前缀和思想:

经典oj题目:《校门外的树-困难 》

在数组arr[]中用arr[i]记录arr[0]~arr[i]的和,这一思想使得我们需要区间[a,b]的和时,只需要调用arr[a-1]和arr[b],通过arr[b]-arr[a-1]就可以得到

剩下的直接看代码吧!

    for (int i = 1; i <= n; i++) {
        int sum=0,num;
        for(int j=1;j<=9;j++) {
            scanf("%d", &num);//分数读入
            if (i>1)arr[i][j] =arr[i-1][j]+num;//记录前缀和
            else arr[i][j] = num;
            sum+=num;
        }
        arr[i][0]=sum+arr[i-1][0];//在arr[i][0]记录综合前缀和,本题因为数值不大,所以可以使用int
    }

例题四:回文姓名

题意:

一个人的姓名中第一个字和最后一个字的拼音相同,则认为该名字为回文姓名

题解:

一道字符串比对题目,本题可以简单分为三类:(1)姓氏的拼音长度大于名(2)姓氏的拼音长度等于名(3)姓氏的拼音长度小于名

第一类,直接输出“no”

第二类,直接判断是否相等

第三题,从第二个字符串末位开始,取出和姓氏相等长度的字符串进行比对;同时需要判断剩余的字母是否符合拼音标准

关于检查标准 :按照题意,只需要检查是否包含韵母即可(要检查合理性的话这题考察的内容就偏了)

    int len1=s1.length(),len2=s2.length();
    if(len1>len2) cout<<"No
";
    else if(len1==len2){
        if(s1==s2)cout<<"Yes
";
        else cout<<"No
";
    }
    else{
        string s3=s2.substr(len2-len1);
        s3[0]= toupper(s3[0]);//令第三个字的首字母大写,方便同姓氏拼音比对
        s2[0]= tolower(s2[0]);//令第二个字的首字母小写,方便韵母比对
        bool flag=(s1==s3);
        int flag2=0;
        for(int j=0;j

例题五:牧夫座空洞 [BFS/DFS]

题意:

三维搜索连续的0的个数,返回最大值

题解:

使用BFS/DFS算法,主要为算法的变式,与常规的BFS题目不同的是,本题是求面积范围而不是给定起点与重点求最短路,所以本题需要自己拟定起点,我给出的代码只能说中规中矩,有很多可以优化的地方,感兴趣的可以自己进行优化。

关于起点的拟定,我这里采用了O(n^3)的复杂度,遍历整个三维数组,应该会有更好的方法

当剩余的“空洞”数量少于当前的max值时,其实不需要继续搜索

(常规bfs优化):在记录是否可以经过的“地图”外侧加上一圈的“障碍物”,这样就不需要进行越界判断

以上为我认为可以优化的两个地方。

代码:

(1)代码一:BFS,使用队列

#include

using namespace std;

struct point {
    int x, y, z;
};

int L, R, C;//记录三个方向的长度
int g[11][11][11];//记录是否为空洞
bool dist[11][11][11];//记录该位置是否被检索过
int dx[] = {1, -1, 0, 0, 0, 0};//方向数组
int dy[] = {0, 0, 1, -1, 0, 0};//方向数组
int dz[] = {0, 0, 0, 0, 1, -1};//方向数组
queue q;//声明一个队列,队列没有学过的可以去看我的往期博客
int bfs(int i, int j, int k) {
    q.push({i,j,k});//起点进入队列
    int v = 0;//记录共有多少个连续的元素
    dist[i][j][k] = true;//标记该点已经走过
    while (!q.empty()) {
        point t = q.front();//获取队头数据
        q.pop();//出队(丢弃)
        v++;
        for (int i = 0; i < 6; i++) {
            int di = t.x + dx[i], dj = t.y + dy[i], dk = t.z + dz[i];
            if (di >= 0 && di < L && dj >= 0 && dj < R && dk >= 0 && dk < C && g[di][dj][dk]==0 && !dist[di][dj][dk]) {
//这一行首先判断了是否越界,然后判断该点是否可以通过,然后判断是否已经过
                dist[di][dj][dk] = true;//标记该点已经走过
                q.push({di, dj, dk});//符合的点,入队
            }
        }
    }
    return v;
}

int main() {
    int t;
    cin >> t;
    while (t--) {
        cin>>L>>R>>C;
        memset(dist, 0, sizeof dist);
        for (int i = 0; i < L; i++)
            for (int j = 0; j < R; j++)
                for (int k = 0; k < C; k++)
                    cin>>g[i][j][k];//输入三维数组
        int ma = 0;
        for (int i = 0; i < L; i++)
            for (int j = 0; j < R; j++)
                for (int k = 0; k < C; k++)
                    if (!dist[i][j][k]&&g[i][j][k]==0)//如果当前的位置未被检索过,且为“空洞”
                        ma = max(ma, bfs(i,j,k));//将改点作为起点进行bfs搜索
        cout << ma << endl;
    }
    return 0;
}

(2)代码二:BFS,使用递归

int bfs(int i, int j, int k) {
    if (i < 0 || i >= L || j < 0 || j >= R || k < 0 || k >= C)return 0;//判断越界
    if (dist[i][j][k] || g[i][j][k] == 1)return 0;//已经走过或者不为“空洞”
    dist[i][j][k] = true;//标记已经走过
    return 1 + bfs(i, j, k + 1) + bfs(i, j, k - 1),bfs(i, j + 1, k), bfs(i, j - 1, k) +bfs(i + 1, j, k), bfs(i - 1, j, k);//向六个方向试探
}

例题六:孤独的岛屿 [并查集]

题意:

岛屿和岛屿之间通过桥梁进行连接,有的岛屿之间有桥梁,有的岛屿之间没有桥梁,但可以经由通往别的岛屿的桥梁绕行到目的岛屿。如果完全无法通行,只能租用水上飞机才能到达该岛屿。以第1座岛屿为起点,想要游历一遍所有的岛屿,并且最终回到第1座岛屿 ,问他至少需要租用多少次水上飞机?

题解:

建立并查集

判断find(i)的值的个数

这里给出两种思路吧

(1)存入set容器,输出set.size()

    setans;
    for(int j=1;j<=m;j++)
        ans.insert(k[find(j)]);
    if(ans.size()==1)cout<<0<

(2)建立一个bool数组 b[],将b[find(i)]=1,再遍历一次bool数组

    for(int j=1;j<=m;j++)
        k[find(j)]=1;
    int ans=0;
    for(int j=1;j<=m;j++)
        if(k[j])ans++;
    if(ans==1)ans=0;
    cout<

第五题使用矩阵快速幂,只能说再等等,可能等不到了(课设太多了啊喂!)

制作:BDT20040


希望对大家有帮助!

对于很多初学者来说,有一群一起学习一起解答的小伙伴很重要!如果你想更好的提升你的编程核心能力(内功)不妨从现在开始!

编程学习书籍分享:

厦门大学嘉庚学院:第九届编程大赛预选赛试题及其解析

编程学习视频分享:

厦门大学嘉庚学院:第九届编程大赛预选赛试题及其解析

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)

欢迎转行和学习编程的伙伴,利用更多的资料学习成长比自己琢磨更快哦!

对于C/C++感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C++的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!

页面更新:2024-03-03

标签:水上飞机   题意   题解   例题   预选赛   数组   岛屿   字典   桥梁   厦门大学   试题   大赛   代码   项目   学院

1 2 3 4 5

上滑加载更多 ↓
Top