2022CCF认证第一轮(CSP-J)真题
三、完善程序题
第一题 枚举因数
从小到大打印正整数n的所有正因数。试补全枚举程序
#include <iostream>
using namespace std;int main(){int n;cin >> n;vector<int> fac;fac.reserve((int)ceil(sqrt(n)));int i;for (i= 1;i*i< n; ++i){if (①) {fac.push back(i);}}for (int k = 0; k< fac.size();++k){cout << ② << " ";}if (③) {cout <<④<<" ";}for (int k= fac.size()-1; k >= 0; --k){cout <<⑤<<;}
}
程序分析:此程序的功能是找出一个给定数n的所有因子。程序的思路是,遍历从1到sqrt(n)的所有数,如果n能被该数整除,则将该数添加到一个vector中。然后再遍历vector,输出所有的因子,同时输出n除以该因子的结果,即另一个因子。 具体分析如下:
- 首先,程序通过cin读取一个整数n。
- 然后,定义一个vector<int>类型的变量fac来保存因子。
- 使用一个for循环,从1开始遍历到sqrt(n)。
- 表达式i*i < n保证了i的取值范围在[1, sqrt(n))之间。
- 在循环中,使用if条件判断n是否能被i整除。
- 如果能整除,则将i添加到fac vector中。
- 循环结束后,通过一个for循环遍历fac vector,按顺序输出所有的因子。
- 如果i*i等于n,说明n是一个完全平方数,此时只需要输出一个因子即可。
- 最后,通过一个逆向的for循环遍历fac vector,输出n除以每个因子的结果,即另一个因子。
单选题
①处应该填
A. n%i== 0
B. n%i== 1
C. n % (i-1)== 0
D. n % (i-1)== 1
答案:A
答案分析:从程序分析中可以得知此处应该是A
②处应该填
A. n / fac[k]
B. fac[k]
C. fac[k]-1
D. n / (fac[k]-1)
答案:B
答案分析:从程序分析中可以得知此处应该是B
③处应该填
A. (i-1)*(i-1)== n
B. (i-1)*i==n
C. i*i== n
D. i*(i-1)== n
答案:C
答案分析:从程序分析中可以得知此处应该是C
④处应该填
A. n-i
B. n-i+1
C. i-1
D. i
答案:D
答案分析:从程序分析中可以得知此处应该是D
⑤处应该填
A. n / fac[k]
B. fac[k]
C. fac[k]-1
D. n / (fac[k]-1)
答案:A
答案分析:从程序分析中可以得知此处应该是A
第二题 洪水填充
现有用字符标记像素颜色的 8x8 图像。颜色填充的操作描述如下:给定起始像素的位置和待填充的颜色将起始像素和所有可达的像素(可达的定义:经过一次或多次的向上、下、左、右四个方向移动所能到达且终点和路径上所有像素的颜色都与起始像素颜色相同),替换为给定的颜色。试补全程序。
#include<iostream>
using namespace std;
const int ROWS = 8;
const int COLS = 8;struct Point {int r, c;Point(int r, int c): r(r), c(c){}
};bool is_valid(char image[ROWS][COLS], Point pt,int prev_color, int new_color){int r= pt.r;int c = pt.c;return (0 <= r && r < ROWS && 0 <=c && c < COLS && ① && image[r][c] != new_color);
}void flood_fill(char image[ROWS][COLS], Point cur, int new_color){queue<Point> queue;queue.push(cur);int prev_color = image[cur.r][cur.c];②;while (!queue.empty()){Point pt = queue.front();queue.pop();Point points[4]={③,Point(pt.r - 1, pt.c),Point(pt.r, pt.c + 1), Point(pt.r, pt.c - 1)};for (auto p : points){if (is_valid(image, p, prev_color, new_color)){④;⑤;}}}
}int main(){char image[ROWS][COLS] = {{'g', 'g', 'g', 'g', 'g', 'g', 'g', 'g'},{'g', 'g', 'g', 'g', 'g', 'g', 'r', 'r'},{'g', 'r', 'r', 'g', 'g', 'r', 'g', 'g'},{'g', 'b', 'b', 'b', 'b', 'r', 'g', 'r'},{'g', 'g', 'g', 'b', 'b', 'r', 'g', 'r'},{'g', 'g', 'g', 'b', 'b', 'b', 'b', 'r'},{'g', 'g', 'g', 'g', 'g', 'b', 'g', 'g'},{'g', 'g', 'g', 'g', 'g', 'b', 'b', 'g'}};Point cur(4, 4);char new_color ='y';flood_fill(image, cur, new_color);for (int r= 0;r< ROWS; r++){for (int c = 0; c< COLS; c++){cout << image[r][c] << " ";}cout << endl;}return 0;
}
//输出
//g g g g g g g g
//g g g g g g r r
//g r r g g r g g
//g y y y y r g r
//g g g y y r g r
//g g g y y y y r
//g g g g g y g g
//g g g g g y y g
程序分析:此程序实现了一个基于队列的洪泛填充算法(BFS),用于填充一个8x8的字符矩阵。该算法从给定的起始点开始,将起始点的颜色替换为新的颜色,并向该点的上下左右四个邻居点进行遍历,如果邻居点的颜色与起始点颜色相同且不等于新的颜色,则将邻居点的颜色替换为新的颜色,并将邻居点添加到队列中继续遍历。 具体的步骤如下:
- 定义一个结构体Point,用于表示矩阵中的一个点,包含行号r和列号c。
- 定义一个函数is_valid,用于判断一个点是否是有效的,即在矩阵范围内,颜色与起始点颜色相同且不等于新的颜色。
- 定义一个函数flood_fill,接受矩阵、起始点和新的颜色作为参数。
- 首先创建一个队列,并将起始点添加到队列中。
- 获取起始点的颜色,并将起始点的颜色替换为新的颜色。
- 使用while循环遍历队列,直到队列为空。
- 在每次循环中,取出队列中的第一个点,并获取其邻居点。
- 遍历邻居点,如果邻居点是有效的,将其颜色替换为新的颜色,并将邻居点添加到队列中。
- 在主函数main中,定义一个8x8的字符矩阵image,并初始化。
- 创建一个起始点cur,坐标为(4, 4)。
- 定义一个新的颜色new_color为'y'。
- 调用flood_fill函数,将矩阵image从起始点cur开始进行洪泛填充。
- 遍历矩阵image,并输出每个点的颜色。
单选题
①处应该填
A. image[r][c]== prev_color
B. image[r][c] != prev color
C. image[r][c] == new_color
D. image[r][c] != new_color
答案:A
答案分析:从程序分析中可以得知此处应该是起始点,答案A
②处应该填
A. image[cur.r+1][cur.c]= new_color
B. image[cur.r][cur.c]= new_color
C. image[cur.r][cur.c+1]= new_color
D. image[cur.r][cur.c]= prev_color
答案:B
答案分析:从程序分析中可以得知此处应该是起始点的颜色替换为新的颜色,答案B
③处应该填
A. Point(pt.r, pt.c)
B. Point(pt.r, pt.c+1)
C. Point(pt.r+1, pt.c)
D. Point(pt.r+1, pt.c+1)
答案:C
答案分析:从程序分析中可以得知此处应该是获取相应的4个邻居点,答案C
④处应该填
A. prev_color = image[p.r][p.c]
B. new_color = image[p.r][p.c]
C. imagelp.r][p.c]= prev_color
D. image[p.r][p.c]= new_color
答案:D
答案分析:从程序分析中可以得知此处应该是邻居点替换为新的颜色,答案D
⑤处应该填
A. queue.push(p)
B. queue.push(pt)
C. queue.push(cur)
D. queue.push(Point(Rows,COLS))
答案:A
答案分析:从程序分析中可以得知此处应该是将邻居点加入队列中,答案A