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

第二次CCF-CSP认证(思路及源码)

第二次CCF-CSP认证

  • 第一道(easy)
    • 思路及AC代码
  • 第二道(easy)
    • 基本思路及AC代码
  • 第三道(mid)
    • 基本思路及AC代码
      • solution 1 (模拟)
      • solution 2(KMP)

第一道(easy)

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

思路及AC代码

#include <bits/stdc++.h>
using namespace std;
//基本思路就是先读一下输入的这堆数字,然后给他排个序,算出每两个相邻数字之间的差值
//然后遍历一下,如果差值为1,用一个外部变量res记录一下啊,否则不做特殊处理
const int N=1010;
int s[N];
int main()
{
    int n;
  cin>>n;
  //读入这堆乱序的数字
  for(int i=0;i<n;i++)
  {
      cin>>s[i];
  }
  sort(s,s+n);//表示从首地址到末尾排一下序 
  int res=0;
  for(int i=0;i<n;i++)
  {
      //遇到的问题:如果用while就意味这遇到差值为1的时候会陷入死循环导致超时
   if(s[i+1]-s[i]==1)
   {
       res++;
   }
  }
  cout <<res<<endl;
  return 0;
}

第二道(easy)

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

基本思路及AC代码

#include <bits/stdc++.h>
using namespace std;
//前言:
//这题如果使用时间复杂度最优的算法需要使用扫描线的知识,但是这题的数据范围十分有限
//我们可以用暴力的思路来解决 时间复杂度是n*nlogn 扫描线可以做到nlogn;
//基本思路:
//题目的意思是给定几个被染色的矩形,我们需要求出并集,并输出

//需要开一个bool数组来标记被染色的矩形
const int N=110;//避免溢出
bool s[N][N];
int main()
{
    int n;
    cin>>n;
    //n表示矩形的个数
    while(n--)
    {
        //在读入之前必须要先定义一下
        int x1,y1,x2,y2;
    cin>>x1>>y1>>x2>>y2;
    //用嵌套for循环先标记一下被染色的数组
    for(int x=x1;x<x2;x++)//当我们标记到最右上角的矩形的时候,实际上的编号并不是x2
    //而是x2-1 所以这里边界需要注意控制一下 纵坐标同理
    for(int y=y1;y<y2;y++)
        s[x][y]=true;
    }
    int res=0;
    //现在我们只需要遍历整个矩形统计一下被染色的矩形即可
    for(int i=0;i<N;i++)
    {
        for(int j=0;j<N;j++)
        {
        if(s[i][j]==true)
        {
            res++;
        }
        }
    }
    cout<<res<<endl;
    return 0;
}

第三道(mid)

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

基本思路及AC代码

在这里插入图片描述

基本思路:KMP算法或者暴力枚举(思路参考y总)
由于本题字符串的长度只有100 可以优先考虑暴力的思路
我们读入一个type0 or1 (注意type是bool类型)表示大小写是否敏感
如果大小写不敏感也就是type=1的时候 我们使用库函数tolower将给定的字符串和目标中所有字母统一变为小写字母 然后再找
如果敏感 我们直接用string里面自带的库函数str.find(s)就能从给出的字符串里找到目标
然后将其输出就好。

solution 1 (模拟)


#include<iostream>
using namespace std;
const int N=110;
string get(string str)
{
    string res;
    for(auto c:str)
        res+=tolower(c);
    return res;
}
int main()
{
    string s;
    cin>>s;
    int n;
    bool type;
    cin>>type>>n;
    while(n--)
    {
        string str;
        cin>>str;
        if(type && str.find(s)!=-1) cout<<str<<endl;
        else if(!type&&get(str).find(get(s))!=-1) cout<<str<<endl;//注意两个字符串都要变成小写
    }
    return 0;
}

solution 2(KMP)

忘记了的话回顾一下我的文章 BP & KMP算法

#include <iostream>
#include <string>

using namespace std;


const int N = 110;

// 函数功能:将字符串中的所有字母转换为小写形式
// 参数:str - 待转换的字符串
// 返回值:转换为小写后的字符串
string get(string str) {
    string res;
    // 遍历字符串中的每个字符
    for (auto c : str) {
        // 将字符转换为小写并添加到结果字符串中
        res += tolower(c);
    }
    return res;
}

// 函数功能:计算 KMP 算法中的 nextval 数组,用于优化字符串匹配过程
// 参数:str - 模式字符串;maxnext - 存储 nextval 值的数组
void GetNextval(string str, int maxnext[]) {
    int j = 0, k = -1;
    // 初始化 nextval 数组的第一个元素为 -1
    maxnext[0] = -1;
    // 遍历模式字符串
    while (j < str.length()) {
        if (k == -1 || str[j] == str[k]) {
            j++;
            k++;
            // 当 str[j] 与 str[k] 不相等时,记录 nextval 值为 k
            if (str[j] != str[k]) {
                maxnext[j] = k;
            } else {
                // 当 str[j] 与 str[k] 相等时,nextval 值取 str[k] 的 nextval 值
                maxnext[j] = maxnext[k];
            }
        } else {
            // 不匹配时,k 回溯到 maxnext[k] 的位置
            k = maxnext[k];
        }
    }
}

// 函数功能:使用 KMP 算法在文本串中查找模式串
// 参数:text - 文本串;pattern - 模式串;next - nextval 数组
// 返回值:若找到匹配,返回模式串在文本串中的起始位置;未找到则返回 -1
int kmpSearch(const string& text, const string& pattern, const int next[]) {
    int i = 0, j = 0;
    while (i < text.length() && j < pattern.length()) {
        if (j == -1 || text[i] == pattern[j]) {
            i++;
            j++;
        } else {
            // 不匹配时,j 回溯到 next[j] 的位置
            j = next[j];
        }
    }
    // 若 j 等于模式串长度,说明找到了匹配
    if (j == pattern.length()) {
        return i - j;
    }
    return -1;
}

int main() {
    string t;
    bool st;
    int n;
    // 输入目标字符串
    cin >> t;
    // 输入是否区分大小写的标志,true 表示区分,false 表示不区分
    cin >> st;
    // 输入待匹配字符串的数量
    cin >> n;

    while (n--) {
        string s;
        // 输入待匹配的字符串
        cin >> s;
        string ss = s;
        string tt = t;

        // 如果不区分大小写,将两个字符串都转换为小写
        if (!st) {
            ss = get(s);
            tt = get(t);
        }

        int next1[N];
        // 计算模式串的 nextval 数组
        GetNextval(tt, next1);

        // 使用 KMP 算法进行字符串匹配
        if (kmpSearch(ss, tt, next1) != -1) {
            // 若找到匹配,输出原始的待匹配字符串
            cout << s << endl;
        }
    }
    return 0;
}


相关文章:

  • 论述AI对学习发展的改变(网页设计)
  • Manus邀请码如何申请,有哪些办法
  • 【MySQL】表的增删查改(CRUD)(下)
  • 迷你世界脚本显示板管理接口:DisPlayBoard
  • vue项目使用svg
  • day1 redis登入指令
  • LeetCode 965题详解 | 单值二叉树的“一统江湖”:如何判断所有节点值全等?
  • Apache ECharts介绍(基于JavaScript开发的开源数据可视化库,用于创建交互式图表)
  • 二进制、八进制、十进制和十六进制间的转换(原理及工程实现)
  • 基于 uni-app 和 Vue3 开发的汉字书写练习应用
  • 【交通网络拓扑图实现原理深度解析】
  • 2.PSCAD是什么软件?
  • 中间件专栏之MySQL篇——MySQL的索引原理
  • 政务信息化项目审计全解析:核心重点与区域实践差异化破局
  • 有效的完全平方数
  • 基于微信小程序的竞赛报名系统设计与实现
  • 《C++ 构造、拷贝构造与析构函数:对象的诞生、克隆与消逝之旅》
  • x86寄存器(二):通用寄存器、指令指针寄存器和标志寄存器
  • 解决Selenium元素拖拽不生效Bug
  • open webui-二次开发-源码启动前后端工程-【超简洁步骤】
  • 德国放弃长期以来的反核立场,寻求修复德法合作关系
  • 西安集中整治监督教育领域不正之风和腐败问题,举报方式公布
  • 90后青年学者李海增逝世9个月后文章登上顶刊,同仁缅怀其贡献
  • 在越剧之乡嵊州,浙江音乐学院越剧学院成立
  • 张宇祥已任上海闵行区委常委、副区长
  • 体坛联播|热刺追平单赛季输球纪录,世俱杯或创收20亿美元