2021蓝桥杯真题图像模糊 C语言/C++

Posted 灬人生如梦

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021蓝桥杯真题图像模糊 C语言/C++相关的知识,希望对你有一定的参考价值。

题目描述
小蓝有一张黑白图像,n×m 个像素组成,其中从上到下共 n 行,每行从左到右 m 列。每个像素由一个 0 到 255 之间的灰度值表示。

现在,小蓝准备对图像进行模糊操作,操作的方法为:

对于每个像素,将以它为中心 3×3 区域内的所有像素(可能是 9 个像素或少于 9 个像素)求和后除以这个范围内的像素个数(取下整),得到的值就是模糊后的结果。

请注意每个像素都要用原图中的灰度值计算求和。

输入描述
输入的第一行包含两个整数 n,m。

第 2 行到第 n+1 行每行包含 m 个整数,表示每个像素的灰度值,相邻整数之间用一个空格分隔。

其中,1≤n,m≤100 。

输出描述
输出 n 行,每行 m 个整数,相邻整数之间用空格分隔,表示模糊后的图像。

输入输出样例
示例 1
输入

3 4
0 0 0 255
0 0 255 0
0 30 255 255
输出

0 42 85 127
5 60 116 170
7 90 132 191
运行限制
最大运行时间:1s
最大运行内存: 128M

所需变量
int a[105][105];//用于存储输入进来的像素

int b[105][105];//用于存储所求模糊像素

int n;//代表行

int m;//代表列

int i,j;//循环变量

int sum;//代表九宫格总数,方便向下取整

思路:我们首先要求这个点周围的八个点,我们需要判断它是否属于最外行,因为如果是最外行,周围可能没有八个像素点,如果强行去取值可能会越界,出现报错,所以我们为了方便去周围的八个点,我们将最外行周围再加上一圈零,这样他就不会影响我们取值,每个点去操作都是一样的,不需要判断他是左上角的点还是右下角的点还是最右边那一列的点

for(i = 1;i<=n;i++)
    for(j = 1;j<=m;j++)
      sum = 0;
      b[i][j] =(a[i-1][j-1] + a[i-1][j] + a[i-1][j+1] + a[i][j-1] + a[i][j] + a[i][j+1] +a[i+1][j-1] +a[i+1][j] +a[i+1][j+1]);
      
      

取到值之后,并不是所有值都是直接除9的,而是你要看他周围有几个像素点,那么这怎么区分呢,只需要判断他们跟n,m之间的关系就能得出!
如果是四个角上的点,那么我们就直接/4,是边上的点就/6,其余的都是/9

if(((i == 1)&&(j == 1))||((i == 1)&&(j == m))||((i == n)&&(j == 1))||((i == n)&&(j == m)))
        b[i][j] = floor(b[i][j]*1.0/4);
        continue;
      
      if(((i == 1)||(j == 1)||(i == n)||(j == m)))
        b[i][j] = floor(b[i][j]*1.0/6);
        continue;
      
      b[i][j] = floor(b[i][j]*1.0/9);
    

最后将得到的数组b按照矩阵的形式输出出来就得到正确答案了!
代码如下(编译器是dev,语言是C语言):

#include <iostream>
#include<math.h>
using namespace std;
int main()

  int a[105][105] = 0,b[105][105],n,m;
  int i,j,sum;
  cin>>n>>m;
  for(i = 1;i<=n;i++)
    for(j = 1;j<=m;j++)
      cin>>a[i][j];
    
  
  for(i = 1;i<=n;i++)
    for(j = 1;j<=m;j++)
      sum = 0;
      b[i][j] =(a[i-1][j-1] + a[i-1][j] + a[i-1][j+1] + a[i][j-1] + a[i][j] + a[i][j+1] +a[i+1][j-1] +a[i+1][j] +a[i+1][j+1]);
      if(((i == 1)&&(j == 1))||((i == 1)&&(j == m))||((i == n)&&(j == 1))||((i == n)&&(j == m)))
        b[i][j] = floor(b[i][j]*1.0/4);
        continue;
      
      if(((i == 1)||(j == 1)||(i == n)||(j == m)))
        b[i][j] = floor(b[i][j]*1.0/6);
        continue;
      
      b[i][j] = floor(b[i][j]*1.0/9);
    
  
  for(i = 1;i<=n;i++)
    for(j = 1;j<=m;j++)
      if(j == 1)
        cout<<b[i][j];
      else
        cout<<" "<<b[i][j];
      
    
    cout<<endl;
  
  return 0;

C语言数组问题?

#include <stdio.h>
int main(void)
char a[]=0;
char *b;
b=&a[0];
scanf("%c%c%c",b,b+1,b+2);
printf("%c%c%c",*b,*(b+1),*(b+2));
scanf("%c%c%c",b+5,b+6,b+7);
printf("%c%c%c",*b,*(b+1),*(b+2));
printf("%c%c%c",*(b+5),*(b+6),*(b+7));
getchar();
getchar();
return 0;

这个为什么不能运行?
放第二次输入时,就会出现问题!

您好,很高兴回答您的问题。
通过阅读您的程序,我想出现错误的原因应该在char a[]=0这句话,因为没有确定数组的长度,所以只能根据后面赋值的数据个数决定数组长度,但是恰好又只赋值了一个数,那么系统就会认定这个数组的长度为1。那么在后面将a[0]的地址赋值给指针变量b,因为a数组只有一个长度,所以后面的b+1,b+2…等等就是不确定的值,所以程序就会出错。
参考技术A

图中红色框内数组声明只有一个元素,也就是说数组大小是1,后面输入3个元素放哪里,放到不是数组的内存里那肯定会失败。

改成char a[10]=0;

注意这样也是只能放10个元素。想要更多改数字。

追问

如果只能放一个数字,那么我为什可以放123三个字符?

追答

你可以使用sizeof(a)看看它多大。你问的这个问题,是因为在c.语言里就算越界也不一定会崩溃,有可能你占用的还是你这个程序的内存空间或者系统没有强制保护的内存,所以给你的错觉是好像也可以用。如果占用保护的就会程序崩溃。

以上是关于2021蓝桥杯真题图像模糊 C语言/C++的主要内容,如果未能解决你的问题,请参考以下文章

蓝桥杯大赛软件赛省赛,C/C++大学B组,改革后2019-2021真题知识点分类

蓝桥杯大赛软件赛省赛,C/C++大学B组,改革后2019-2021真题知识点分类

蓝桥杯赛前冲刺-枚举暴力和排序专题2(包含历年蓝桥杯真题和AC代码)

第十二届蓝桥杯省赛第二场C++B组 真题题解(详细讲解+代码分析)看这篇就够了~~~

算法笔记_213:第七届蓝桥杯软件类决赛部分真题(Java语言C组)

2022年4月蓝桥杯软件类省赛:真题+解析