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

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

第六次CCF-CSP认证

  • 数位之和(easy)
    • 思路及AC代码
    • 遇到的问题
  • 开心消消乐(easy)
    • 思路及AC代码
  • 画图(mid)
    • 思路及AC代码

数位之和(easy)

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

思路及AC代码

既然题目要求我们输出各位数字之和,那么我们之间把这些个位 十位…上的数拿到不就行了,一开始我还想着写一个函数去搞到这个输入n的每一位,返回一个数组,但是首先我们不知道传进来的数字是个几位数,其次就算知道也挺麻烦的,我后来想了一下,我直接把这个数搞成字符串不就行了吗,这样 这个数就不是一个整型,一个整体,而是刚刚好是我需要的 由若干个数字组成的字符串,ok,代码来咯:

#include <bits/stdc++.h>
using namespace std;
int main()
{
    string n;
    cin>>n;
    int res=0;
    for(auto c:n)
    {
        res+=c-'0';
    }
    cout<<res<<endl;
    return 0;
}

遇到的问题

在这里插入图片描述

开心消消乐(easy)

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

思路及AC代码

对于矩阵中的每个元素 s[i][j],使用四个变量 left、right、up 和 under 分别记录该元素向左右上下四个方向扩展的边界位置。
初始化 left 和 right 为当前列 j,up 和 under 为当前行 i。
使用四个 while 循环分别向左右上下四个方向扩展,直到遇到不同的数字或超出矩阵边界为止。
计算横向连续相同数字的长度为 right - left - 1,纵向连续相同数字的长度为 under - up - 1。
如果横向或纵向的连续长度大于等于 3,则将 p[i][j] 标记为 true,表示该位置可以消除;否则标记为 false。

#include <bits/stdc++.h>
using namespace std;
const int N =33;//多开几个
int s[N][N];
bool p[N][N];//状态数组
int main()
{
  int n,m;
  cin>>n>>m;
  for(int i=0;i<n;i++)
  {
      for(int j=0;j<m;j++)
      {
          cin>>s[i][j];
      }
  }
  
  for(int i=0;i<n;i++)
  {
      for(int j=0;j<m;j++)
      {
        int left=j,right=j,up=i,under=i;
        int x=s[i][j];//目前的位置
          while(left>=0 && s[i][left]==x) left--;
          while(right<m && s[i][right]==x) right++;
          while(up>=0 && s[up][j]==x) up--;
          while(under<n && s[under][j]==x) under++;
          //由某个点向四周扩展
        p[i][j]=right-left-1>=3 || under-up-1>=3;
        //如果相同数字长度大于等于3则标记为可以消除
        //下面是对这行代码的分步骤解释
      }
  }
  
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
//解释:
   // 计算左右方向相同数字的连续长度
            int leftRightLength = right - left - 1;

            // 计算上下方向相同数字的连续长度
            int upUnderLength = under - up - 1;

            // 判断左右或上下方向的连续长度是否大于等于 3
            bool canEliminate = leftRightLength >= 3 || upUnderLength >= 3;

            // 将判断结果存储到状态数组 p 中
            p[i][j] = canEliminate;
、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、、
  
  for(int i=0;i<n;i++)
  {
      for(int j=0;j<m;j++)
      {
          if(p[i][j])
          {
              cout<<0<<' ';
          }else{
              cout<<s[i][j]<<' ';
          }
      }
      cout<<endl;
  }
  return 0;
}

画图(mid)

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

思路及AC代码

分析:
给定一个 m * n 的画布,初始画布上每个位置用点来填充 可以把每一个方块理解为一个像素
这题就两种操作(输入):
操作 0(画线):在画布上画线段,水平线段用 - 表示,垂直线段用 | 表示,线段交叉处用 + 表示。

操作 1(染色):从指定位置开始进行填充操作,将该位置及其连通区域(不跨越线段)填充为指定字符。
思路

画线段操作:对于操作 0,输入两个端点坐标,将两点之间的线段绘制在画布上。若线段交叉,交叉处标记为 +。

填充操作:对于操作 1,使用深度优先搜索(DFS)算法从指定位置开始填充,遇到线段则停止填充。(dfs如果有问题就去看一下我之前的文章迷宫问题)

下面这是yxc课上的代码 我用AI生成注释后供大家参考:

#include <iostream>
#include <cstring>
#include <algorithm>

using namespace std;

const int N = 110;

int n, m, Q;//Q表示询问次数
char g[N][N];  // 存储图形的二维数组,记录每个位置的字符
bool st[N][N]; // 标记数组,用于深度优先搜索中记录对应位置是否已访问过
int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1}; // 定义上下左右四个方向的坐标偏移量 类似迷宫问题

// 深度优先搜索函数,用于填充颜色
// x, y:当前处理的坐标位置;c:要填充的目标字符
void dfs(int x, int y, char c) {
    st[x][y] = true; // 标记当前位置已访问,避免重复处理
    g[x][y] = c; // 将当前位置的字符设置为目标填充字符
    for (int i = 0; i < 4; i++) { // 遍历四个方向(上、右、下、左)
        int a = x + dx[i], b = y + dy[i]; // 计算相邻位置的坐标
        // 检查相邻位置是否在图形范围内,且未被访问过
        if (a >= 0 && a < m && b >= 0 && b < n && !st[a][b]) {
            // 若该位置是线条字符('-'、'|'、'+'),则不进行填充
            if (g[a][b] == '-' || g[a][b] == '|' || g[a][b] == '+') continue;
            dfs(a, b, c); // 递归处理相邻位置,实现颜色填充
        }
    }
}

int main() {
    cin >> m >> n >> Q; // 输入图形的行数m、列数n,以及操作次数Q
    // 初始化图形数组,将所有位置设置为默认字符'.'
    for (int i = 0; i < m; i++)
        for (int j = 0; j < n; j++)
            g[i][j] = '.';

    while (Q--) { // 循环处理每一次操作
        int op;
        cin >> op;
        if (op == 0) { // 画矩形操作
            int x1, y1, x2, y2;
            cin >> x1 >> y1 >> x2 >> y2;
            // 调整坐标,确保x1 <= x2,y1 <= y2
            if (x1 > x2) swap(x1, x2);
            if (y1 > y2) swap(y1, y2);
            // 遍历矩形区域内的所有位置
            for (int i = x1; i <= x2; i++) {
                for (int j = y1; j <= y2; j++) {
                    auto &t = g[i][j]; // 取当前位置字符的引用,方便修改
                    // 处理矩形边界的特殊字符情况(将交叉处设为'+')
                    if (x1 == x2 && t == '-' || y1 == y2 && t == '|' || t == '+') 
                        t = '+';
                    else { // 根据矩形是横线还是竖线,设置对应字符
                        if (x1 == x2) t = '|'; // 竖线矩形
                        if (y1 == y2) t = '-'; // 横线矩形
                    }
                }
            }
        } else { // 填充操作(op == 1)
            int x, y;
            char c;
            cin >> x >> y >> c;
            memset(st, 0, sizeof st); // 重置访问标记数组
            dfs(x, y, c); // 调用深度优先搜索进行颜色填充
        }
    }

    // 输出图形,注意此处进行了坐标转换(行列交换)
    for (int i = n - 1; i >= 0; i--) {
        for (int j = 0; j < m; j++)
            cout << g[j][i]; // 按转换后的坐标输出字符
        cout << endl; // 每行输出结束后换行
    }

    return 0;
}

http://www.kler.cn/a/579870.html

相关文章:

  • Elasticsearch 入门教学:从零开始掌握分布式搜索引擎
  • ESP32的IDF开发学习-移植lvgl并显示简单ui(以gc9a01为例)
  • 内网安全-横向移动PTH 哈希PTT 票据PTK 密匙Kerberos密码喷射
  • 蓝桥杯备考:离散化详解
  • 数据结构:有序表的插入
  • MongoD和关系型数据库相关概念的对应
  • PyTorch 张量数据类型定义和转换
  • 【Linux内核系列】:深入理解缓冲区
  • 在ubuntu 24 命令行 下,制作无人值守ubuntu-24.04.2-desktop 桌面版安装U盘
  • 《深入理解Linux:高效崩溃分析与实时栈回溯技巧》
  • 操作系统知识点25
  • OCR图片识别原理
  • C++:面向对象之多态(运算符重载)
  • AF3 squeeze_features函数解读
  • Vue3 Pinia 符合直觉的Vue.js状态管理库
  • 超越经典:量子通信技术的发展与未来
  • MySQL8.0窗口函数
  • HTML 表格详解(简单易懂较详细)
  • 云服务运维智能时代:阿里云操作系统控制台
  • 利用paddleocr解决图片旋转问题