当前位置: 首页 > news >正文

第三次CCF-CSP认证(含C++源码)

第三次CCF-CSP认证

  • 第一道(easy)
    • 思路及AC代码
      • solution 1(模拟)
      • solution 2 (哈希表)
  • 第二道(easy but mid for me)
    • 思路及AC代码
      • solution 1
        • 遇到的问题
      • solution 2
    • 第三题(mid)
    • 基本思路及AC代码
  • 结语

第一道(easy)

在这里插入图片描述
题目链接

思路及AC代码

solution 1(模拟)

#include <bits/stdc++.h>
using namespace std;
const int N =1010;
int n;
int s[N];
//基本思路:使用数组模拟哈希表实现 本质上是编号和来访次数之间的映射
int main()
{
    cin>>n;
    while(n--)
    {
       int x;
       cin>>x;
       s[x]++;//本质上就是哈希表
       cout<<s[x]<<" ";//控制输入输出 这里不能用endl
    }
    return 0;
}

solution 2 (哈希表)

#include <iostream>
#include <unordered_map>
#include <vector>


using namespace std;

int main() {
    int n;
    // 读取记录的条数
    cin >> n;
    vector<int> records(n);
    // 自定义的哈希表,用于存储每个读者编号出现的次数
    unordered_map<int, int> study_hard;

    // 读取每条记录中的读者编号
    for (int i = 0; i < n; ++i) {
        cin >> records[i];
    }

    // 遍历每条记录,统计每个读者编号出现的次数
    for (int i = 0; i < n; ++i) {
        int readerId = records[i];
        // 如果该读者编号是第一次出现,初始化为 1
        if (study_hard.find(readerId) == study_hard.end()) {
            study_hard[readerId] = 1;
        } else {
            // 否则,将该读者编号的出现次数加 1
            ++study_hard[readerId];
        }
        // 输出该读者编号是第几次出现
        cout << study_hard[readerId]<<" ";
     
        }
   
    return 0;
}

第二道(easy but mid for me)

在这里插入图片描述
题目链接

思路及AC代码

solution 1

讲解视频
首先我们拿到这个题目不要慌,一看这个图这么复杂,又是左右上下又是斜着移动,其实我们只要找准规律,给出限制条件,就能AC,这个方法是我在B站上学习的,我们将题中的矩阵放在直角坐标系中并给他们编个号(左上角坐标),将左上角看做原点
分析:什么是限制?
对于这题而言我们需要按蛇形输出矩形的坐标 ,同时也意味着我们不能超过这个矩形的范围,我们仔细观察一下,在这个图中的运动轨迹如果只是上下左右走,边界是很好控制的,只需要不超过矩形的边长就行(条件3),但是这题是个蛇形 还特么是斜着的,所以我们要着重处理两个方向(direction)左下和右上,也就分别对应下图中绿色和蓝色的箭头。
solution:我们先处理一下右上,也就是当我们的纵坐标小于0的时候(j<0),我们需要将这个非法的移动方向给他调整一下,具体就是让j=0,这样就变成向右移动了,然后紧接着我们需要向左下方移动(direction 1)也就是j++,i–,这样我们就给出了一个完整的限制条件 左下同理(条件 1、2)

在这里插入图片描述

#include <iostream>
using namespace std;

int main() {
    int n;
    cin >> n;
    // 动态分配二维数组 一开始用静态分配内存直接爆栈了哈哈哈
    int** a = new int*[n];
    for (int i = 0; i < n; ++i) {
        a[i] = new int[n];
    }

    int dir = 2;
    int i = 0;
    int j = 0;

    // 输入矩阵
    for (i = 0; i < n; i++) {
        for (j = 0; j < n; j++) {
            cin >> a[i][j];
        }
    }

    i = 0;
    j = 0;
    // 输出矩阵元素
    while (1) {
        // 输出当前元素
        cout << a[i][j] << " ";

        // 判断是否到达矩阵右下角元素,若是则退出循环
        if (i == n - 1 && j == n - 1) {
            break;
        }

        switch (dir) {
        case 1: // 左下方向
            i++;
            j--;
            break;
        case 2: // 右上方向
            i--;
            j++;
            break;
        }

        // 处理越界情况,调整方向和位置
        if (i < 0 || j >= n) {
            if (j >= n) {
                i = i + 2;
                j = n - 1;
            }
            else {
                i = 0;
            }
            dir = 1;
        }
        else if (j < 0 || i >= n) {
            if (i >= n) {
                j = j + 2;
                i = n - 1;
            }
            else {
                j = 0;
            }
            dir = 2;
        }
    }

    // 释放动态分配的内存
    for (int i = 0; i < n; ++i) {
        delete[] a[i];
    }
    delete[] a;

    return 0;
}
遇到的问题

在原来的代码里使用了 int a[N][N]; 来定义二维数组,这里的 N 是一个宏定义,数组是在栈上分配内存的。栈的空间通常是有限的,当矩阵规模(即 n 的值)比较大时,a[N][N] 所需的内存会超出栈的可用空间,从而导致栈溢出错误。
矩形比较小:
在这里插入图片描述
矩形比较大:
在这里插入图片描述

solution 2

这个方法是抓住了斜对角线的性质即横纵坐标之和正好是这条对角线的序号,通过补全这个矩形的下方和右方 就可以做到只需要按两个方向遍历输出即可
在这里插入图片描述
在这里插入图片描述

#include <bits/stdc++.h>
// 定义一个常量 N 为 510,用于表示矩阵的最大规模
const int N = 510;
// 定义变量 n 用于存储矩阵的实际规模
int n;
// 定义二维数组 q 用于存储矩阵元素,q[i][j] 表示矩阵第 i 行第 j 列的元素
int q[N][N];

int main ()
{
    // 从标准输入读取一个整数 n,作为矩阵的行数和列数
    scanf("%d",&n);
    // 使用两层嵌套循环遍历矩阵的每一个元素
    for(int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            // 从标准输入读取矩阵第 i 行第 j 列的元素,并存储到 q[i][j] 中
            scanf("%d", &q[i][j]);

    // 外层循环控制遍历的对角线编号,从 2 到 2 * n
    // 矩阵的对角线编号从 2 开始(因为左上角元素是第 2 条对角线),最大到 2 * n
    for (int i = 2; i <= n * 2; i++)
    {
        // 判断当前对角线编号是否为偶数
        if (i % 2 == 0)
        {
            // 对于偶数编号的对角线,从下往上遍历
            // 从对角线的最后一个可能的元素开始,逐步向上遍历
            for (int j = i - 1; j >= 1; j--)
                // 检查当前元素的行和列是否在矩阵范围内
                // j 表示行,i - j 表示列
                if (j >= 1 && j <= n && i - j >= 1 && i - j <= n)
                    // 如果元素在矩阵范围内,输出该元素,并在后面添加一个空格
                    printf("%d ", q[j][i - j]);
        }
        else
        {
            // 对于奇数编号的对角线,从上往下遍历
            // 从对角线的第一个可能的元素开始,逐步向下遍历
            for (int j = 1; j <= i; j++)
                // 检查当前元素的行和列是否在矩阵范围内
                // j 表示行,i - j 表示列
                if (j >= 1 && j <= n && i - j >= 1 && i - j <= n)
                    // 如果元素在矩阵范围内,输出该元素,并在后面添加一个空格
                    printf("%d ", q[j][i - j]);
        }
    }
    return 0;
}

第三题(mid)

在这里插入图片描述
题目链接

基本思路及AC代码

明天更一下 困了懒得写了

结语

估计这篇文章之后我的粉丝就到200了,还是感谢各位支持,其实一开始我写博客也只是为了记录一下,但是没想到写着写着就会发现第一遍学的时候有很多遗漏或者囫囵吞枣,这样就强迫自己学的更深入了,同时在遇到一些计算机相关问题的时候我都会优先在CSDN上搜索,收获颇丰,那么 希望看到这里的你有美好的一天!我会保持更新,请多多三连!!!最后送给大家一句话“先完成,再完美,just right now”
*********************************************************************************************signed by 曦月逸霜

相关文章:

  • Redis数据结构深度解析:从String到Stream的奇幻之旅(一)
  • Clion快捷键、修改字体
  • 深度学习系列78:使用langchain的api进行RAG
  • 介绍exadata中的smart Scan技术
  • Java在小米SU7 Ultra汽车中的技术赋能
  • 回归预测 | Matlab实现GWO-BP-Adaboost基于灰狼算法优化BP神经网络结合Adaboost思想的回归预测
  • TDengine SQL手册—删除数据
  • Springboot中的VO、PO、DAO、BO、DTO、POJO
  • 测试周期紧张?功能与非功能测试的 5 个平衡策略
  • 数学建模笔记——层次分析法(AHP)
  • Qt信号与槽机制实现原理
  • 《DeepSeek MoE架构下,动态专家路由优化全解析》
  • 微信小程序+SpringBoot的单词学习小程序平台(程序+论文+讲解+安装+修改+售后)
  • bootstrap接入kkFileView
  • 对deepseek进行微调
  • IntelliJ IDEA 中配置 Groovy
  • 虚幻基础:蓝图接口
  • 【数据结构】第六章:图
  • vue使用slot时子组件的onUpdated执行问题
  • React基础之组件通信
  • 提高网站加载速度iis/营销与销售的区别
  • 域名到期对网站的影响/国外seo工具
  • 做网站还有价值吗/湖南中高风险地区
  • 慈溪怎么做网站/百度信息流代理
  • vs2015是网站开发/真正永久免费网站建设
  • 南昌网站搜索排名/网络优化主要做什么