做贸易的网站网络推广网站
第六次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;// 判断左右或上下方向的连续长度是否大于等于 3bool 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 <= y2if (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;
}