牛客竞赛题库(NC52069)
#include<stdio.h> #include<string.h> int main() { int n, m; char a[1002][1002]; int count = 0; scanf("%d %d", &n, &m); getchar(); for (int i = 0; i < n; i++) { fgets(a[i], 1002, stdin); a[i][strcspn(a[i], "\n")] = '\0'; } for(int i = 0;i < n;i++) { for(int j = 0;j < m;j++) { if(a[i][j]!='*') { count=0; for (int k = (i - 1 < 0? 0 : i - 1); k <= (i + 1 >= n? n - 1 : i + 1); k++) { for (int l = (j - 1 < 0? 0 : j - 1); l <= (j + 1 >= m? m - 1 : j + 1); l++) { if (a[k][l] == '*') { count++; } } } a[i][j]=count+48; } } } for (int i = 0; i < n; i++) { puts(a[i]); } return 0; }
首先说一下头文件,stdio.h是提供这个代码中的fgets输入函数,string.h提供了strcspn字符串操作函数。
这里定义了n,m;用于储存二维字符数组a的行数和列数,这里的a[1002][1002]是一个二维字符数组,用于储存数据,为什么是1002,因为根据题目中备注的范围,我们需要取比1000大的数,防止溢出,count用于记步数。
第11行的getchar()用于读取并丢弃输入中scanf之后残留的换行符,防止影响后续fgets的输入。
这里讲解一下fgets和strcspn函数
fgets函数
函数原型:char *fgets(char *str, int n, FILE *stream)
str: 指向字符数组的指针,用于存储读取到的字符串。
n:一个整数,表示要读取的最大字符数(包括字符串结束符'\0')。如果读取到n-1个字符或遇到换行符'\n'时,读取操作就会停止。
stream:指向FILE类型的指针,表示输入流,常用的是stdin(标准输入流,即从键盘输入)。
功能:如果成功读取字符串,返回指向存储字符串的字符数组str的指针;如果发生错误,返回NULL。
strcspn函数
函数原型:size_t strcspn(const char *str1, const char *str2);
str1:指向要进行搜索的字符串的指针。
str2:指向包含要搜索字符的字符串的指针。
功能:简单来说,就是返回str1中不包含str2中字符的前缀长度。
举个小例子(这里不详细写完整代码,只是辅助理解该函数):
char str1[] = "hello world"; char str2[] = "w"; size_t res = strcspn(str1, str2); printf("%zu\n", result);
这里返回的结果是6,因为从str1的开头到'w'前面的字符数是6(即hello和一个空格)
for (int i = 0; i < n; i++) { fgets(a[i], 1002, stdin); a[i][strcspn(a[i], "\n")] = '\0'; }
这里利用for循环,利用fgets函数输入字符串到二维数组a中,fgets最多读取1001个字符(第1002个位置留给字符串结束符'\0')。利用strcspn函数找到a[i]字符串中换行符'\n'的位置,然后然后将该位置的字符替换为字符串结束符'\0',从而达到去除换行符的目的。
for(int i = 0;i < n;i++) { for(int j = 0;j < m;j++) { if(a[i][j]!='*') { count=0; for (int k = (i - 1 < 0? 0 : i - 1); k <= (i + 1 >= n? n - 1 : i + 1); k++) { for (int l = (j - 1 < 0? 0 : j - 1); l <= (j + 1 >= m? m - 1 : j + 1); l++) { if (a[k][l] == '*') { count++; } } } a[i][j]=count+48; } } }
外层两个嵌套的for循环用于遍历二维数组a的每一个元素,当元素a[i][j]不是'*'时,进入内层两个嵌套的for循环,用于遍历该元素周边的元素(包括自身位置)。如果周边元素是'*',则count自增。最后将统计得到的count加上48(48是字符'0'的ACSll码值,这样做是将数字转换为对应字符),储存到a[i][j]位置,并将count重置为0。
我们举个例子讲解一下运行过程,便于理解
for (int i = 0; i < n; i++) { puts(a[i]); }
通过for循环逐行使用puts函数输出处理后的矩阵a,puts函数会自动在输出字符串后面添加换行符。
这是我对题库写的代码以及分析,由易到难,我会坚持把它写完,可能有些粗糙,专栏免费,不想看可以划走。