文章目录
- 一、前言
- 二、问题
- 问题:1407. 图像相似度
- 问题:1330. 求最大梯形的面积
- 问题:1384. 靶心数
- 问题:1398. 奇偶统计
- 三、感谢
一、前言
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
本章节主要对,包括《1407. 图像相似度》《1330. 求最大梯形的面积》《1384. 靶心数》《1398. 奇偶统计》题目。
二、问题
问题:1407. 图像相似度
类型:二维数组
题目描述:
给出两幅相同大小的黑白图像(用 0−1 矩阵表示,0 代表白色,1 代表黑色)表示,求它们的相似度。
说明:若两幅图像在相同位置上的像素点颜色的值相同,则称它们在该位置具有相同的像素点。两幅图像的相似度定义为相同像素点数占总像素点数的百分比。
比如:输入
2 2
1 0
0 1
1 1
1 1
数据解释:第一行的 2 2 表示图像的尺寸是 2 行,每行 2 个整数;接下来的两行数据 1 0 和 0 1 表示第一幅图片的数值,再接下来两行数据 1 1 和 1 1 表示第二幅图片的数值;
从数据上可以看出,两幅图片有 2 个数是相等的,因此两幅图片的相似度为 50%,实际输出不需要输出百分号,结果保留 2 位小数,因此实际输出 50.00 。
输入:
第一行包含两个整数 n 和 m ,表示图像的行数和列数,中间用单个空格隔开。(1≤n,m≤100)
之后 n 行,每行 m 个整数 0 或 1 ,表示第一幅黑白图像上各像素点的颜色。相邻两个数之间用单个空格隔开。
之后 n 行,每行 m 个整数 0 或 1 ,表示第二幅黑白图像上各像素点的颜色。相邻两个数之间用单个空格隔开。
输出:
一个小数,表示相似度(以百分比的形式给出,但百分号不需要显示),精确到小数点后两位。
样例:
输入:
3 3
1 0 1
0 0 1
1 1 0
1 1 0
0 0 1
0 0 1
输出:
44.44
1.分析问题
-
已知:两幅相同大小的黑白图像(用 0?1 矩阵表示,0 代表白色,1 代表黑色);
-
未知:求它们的相似度(不需要输出百分号,结果保留 2 位小数)。
-
关系:两幅图像的相似度定义为相同像素点数占总像素点数的百分比。
2.定义变量
- n:存储图像的行数。
- m:存储图像的列数。
- p:二维数组,用于存储第一幅图像的像素值。
- xs:双精度浮点型变量,用于存储相同像素点的数量。
//二、数据定义
int n,m,p[101][101];
double xs=0;
3.输入数据
- 通过cin输入第一幅图像的行数n和列数m。
- 再通过两层循环输入第一幅图像的每一个像素值。
//三、数据输入
cin>>n>>m;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
cin>>p[i][j];
}
}
4.数据计算
- 对于第二幅图像的每一个像素值,在输入的同时与第一幅图像对应位置的像素值比较。
- 如果两个图像在同一位置的像素值相同,则将xs加1。
//四、数据计算
int t;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
cin>>t;
if(t==p[i][j]) ++xs;
}
}
5.输出
- 使用fixed和setprecision(2)设置输出格式,确保输出的相似度保留两位小数。
- 输出相似度,即相同像素点的数量除以总的像素点数量再乘以100,得到百分比形式的相似度。
//五、输出结果
cout<<fixed<<setprecision(2)<<xs*100/n/m;
完整代码如下:
#include <bits/stdc++.h> // 包含所有标准库,适用于竞赛环境,但不推荐在正式项目中使用
using namespace std; // 为了简化代码,使用标准命名空间
int main() {
// 问题分析
// 已知条件:两幅相同大小的黑白图像(用 0-1 矩阵表示,0 代表白色,1 代表黑色)。
// 求解:求它们的相似度(不需要输出百分号,结果保留 2 位小数)。
// 关系:两幅图像的相似度定义为相同像素点数占总像素点数的百分比。
// 数据定义
int n, m; // 图像的行数和列数
int p[101][101]; // 第一幅图像的矩阵
double xs = 0; // 相同像素点的数量
// 数据输入
cin >> n >> m; // 输入第一幅图像的行数n和列数m
for (int i = 0; i < n; ++i) { // 输入第一幅图像的数据
for (int j = 0; j < m; ++j) {
cin >> p[i][j];
}
}
// 数据计算
int t; // 临时变量,用于存储第二幅图像的每个像素值
for (int i = 0; i < n; ++i) { // 输入第二幅图像的数据,并同时计算相同像素点的数量
for (int j = 0; j < m; ++j) {
cin >> t;
if (t == p[i][j]) {
++xs; // 如果当前像素相同,则增加相同像素点计数器
}
}
}
// 输出结果
cout << fixed << setprecision(2) << xs * 100 / (n * m); // 输出相似度,保留两位小数
return 0; // 程序正常结束
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1330. 求最大梯形的面积
类型:二维数组
题目描述:
从键盘读入 n ( 3≤n≤100 )个梯形的上底、下底和高,请问这 n 个梯形中,最大面积的梯形的面积是多少?
(梯形面积的求解公式为 S=(a+b)×h/2 ,也就是 (上底+下底)×高/2 )
输入:
第 1 行为 1 个整数 n ,接下来 n 行每行 3 个整数分别代表梯形的上底、下底和高。
输出:
最大面积梯形的面积(结果保留 1 位小数)
样例:
输入:
3
1 2 3
3 4 5
2 3 4
输出:
17.5
1.分析问题
-
已知: n ( 3≤n≤100 )个梯形的上底、下底和高;
-
未知:请问这 n 个梯形中,最大面积的梯形的面积是多少?(结果保留 1 位小数)
-
关系:梯形面积的求解公式为 S=(a+b)×h/2 。
2.定义变量
- n:存储梯形的数量。
- a、b、h:分别存储梯形的上底、下底和高。
- s:双精度浮点型变量,用于存储最大面积。
- t:双精度浮点型变量,用于存储当前梯形的面积。
//二、数据定义
int n,a,b,h;
double s=0,t;
3.输入数据
- 通过cin输入梯形的数量n。
- 再通过两层循环输入每个梯形的上底、下底和高。
//三、数据输入
cin>>n;
4.数据计算
- 在输入每个梯形的数据的同时,计算每个梯形的面积t。
- 使用公式 (a + b) * h / 2.0 来计算面积。
- 如果当前梯形的面积t大于之前记录的最大面积s,则更新最大面积s。
//四、数据计算
for(int i=0;i<n;++i){
cin>>a>>b>>h;
t=(a+b)*h/2.0;
s=s>t?s:t;
}
5.输出
- 使用fixed和setprecision(1)设置输出格式,确保输出的最大面积保留一位小数。
//五、输出结果
cout<<fixed<<setprecision(1)<<s;
完整代码如下:
#include <bits/stdc++.h> // 包含所有标准库,适用于竞赛环境,但不推荐在正式项目中使用
using namespace std; // 为了简化代码,使用标准命名空间
int main() {
// 问题分析
// 已知条件:有 n 个梯形的上底、下底和高(3 ≤ n ≤ 100)。
// 求解:求这 n 个梯形中最大面积的梯形的面积(结果保留 1 位小数)。
// 关系:梯形面积的求解公式为 S = (a + b) × h / 2。
// 数据定义
int n, a, b, h; // 定义梯形的上底a、下底b、高h以及梯形的数量n
double s = 0, t; // s 用于保存最大面积,t 用于保存当前梯形的面积
// 数据输入
cin >> n; // 输入梯形的数量 n
// 数据计算
for (int i = 0; i < n; ++i) { // 循环读取每个梯形的信息
cin >> a >> b >> h; // 输入当前梯形的上底a、下底b和高h
t = (a + b) * h / 2.0; // 计算当前梯形的面积
if (t > s) { // 如果当前梯形的面积大于之前记录的最大面积
s = t; // 更新最大面积
}
}
// 输出结果
cout << fixed << setprecision(1) << s; // 输出最大面积,保留一位小数
return 0; // 程序正常结束
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1384. 靶心数
类型:二维数组
题目描述:
James 同学发现了在二维数组中有这样一类数,这个数正好比自己上下左右四个方向的数都大(由于需要比四个方向的数都大,因此这个数不可能在第一行、最后一行、第一列、最后一列), James 把它们称为靶心数。
请你编程求出一个二维数组的靶心数有哪些,输出他们。
输入:
第一行是两个整数 n 和 m(n 和 m 都是 4∼100 之间的整数),代表接下来的二维数组有 n 行 m 列。
接下来 n 行,每行有 m 个整数。
输出:
请按照输入的顺序输出满足条件的靶心数,每行 1 个。
样例:
输入:
4 4
1 2 3 4
5 6 5 8
9 1 11 10
13 4 5 16
输出:
6
11
1.分析问题
- 已知:二维数组;
- 未知:求出一个二维数组的靶心数有哪些,输出他们;
- 关系:这个数正好比自己上下左右四个方向的数都大(由于需要比四个方向的数都大,因此这个数不可能在第一行、最后一行、第一列、最后一列)。
2.定义变量
- n:存储二维数组的行数。
- m:存储二维数组的列数。
- a:二维数组,用于存储输入的数字。
//二、数据定义
int n,m,a[101][101];
3.输入数据
- 通过cin输入二维数组的行数n和列数m。
- 再通过两层循环输入二维数组的每一个元素。
//三、数据输入
cin>>n>>m;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
cin>>a[i][j];
}
}
4.数据计算
- 遍历数组的每一个非边界元素(即排除第一行、最后一行、第一列和最后一列的元素)。
- 对于每一个非边界元素,检查它是否比它的上、下、左、右四个方向的数都大。
- 如果满足条件,则输出这个数。
//四、数据计算
for(int i=1;i<n-1;++i){
for(int j=1;j<n-1;++j){
if(a[i][j]>a[i-1][j]&&a[i][j]>a[i][j-1]&&a[i][j]>a[i][j+1]&&a[i][j]>a[i+1][j]) cout<<a[i][j]<<endl;
}
}
完整代码如下:
#include <bits/stdc++.h>
using namespace std;
int main() {
// 问题分析
// 已知条件:一个二维数组。
// 求解:找出这个二维数组中的“靶心数”并输出。
// 关系:这个数正好比自己上下左右四个方向的数都大(由于需要比四个方向的数都大,因此这个数不可能在第一行、最后一行、第一列、最后一列)。
// 数据定义
int n, m; // 定义二维数组的行数n和列数m
int a[101][101]; // 定义二维数组a用于存储输入的数字
// 数据输入
cin >> n >> m; // 输入二维数组的行数n和列数m
for (int i = 0; i < n; ++i) { // 逐行输入二维数组的值
for (int j = 0; j < m; ++j) {
cin >> a[i][j]; // 输入当前单元格的值
}
}
// 数据计算
// 注意:由于靶心数不能位于数组的边缘,所以i和j的范围从1到n-2和m-2
for (int i = 1; i < n - 1; ++i) { // 遍历数组的每一行(排除边界)
for (int j = 1; j < m - 1; ++j) { // 遍历数组的每一列(排除边界)
if (a[i][j] > a[i - 1][j] && // 当前数大于上方的数
a[i][j] > a[i + 1][j] && // 当前数大于下方的数
a[i][j] > a[i][j - 1] && // 当前数大于左边的数
a[i][j] > a[i][j + 1]) { // 当前数大于右边的数
cout << a[i][j] << endl; // 输出当前数
}
}
}
return 0; // 程序正常结束
}
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》
问题:1398. 奇偶统计
类型:二维数组
题目描述:
在一个n行m列的二维数组中,有若干奇数和偶数,请编程统计出这个二维数组中,奇数和偶数分别有多少个?
输入:
第一行是两个整数n和m(n和m都是4~100之间的整数),代表接下来的二维数组有n行m列。
接下来n行,每行有m个整数。(这些整数都是0~9999之间的整数)
输出:
两个整数用空格隔开,分别代表二维数组中奇数、偶数的个数
样例:
输入:
2 2
2 3
4 6
输出:
1 3
1.分析问题
- 已知:一个n行m列的二维数组;
- 未知:统计出这个二维数组中,奇数和偶数分别有多少个?
- 关系:模运算、累计和。
2.定义变量
- n:存储二维数组的行数。
- m:存储二维数组的列数。
- t:临时变量,用于存储输入的每一个元素。
- odd:用于计数奇数的数量。
- even:用于计数偶数的数量。
//二、数据定义
int n,m,t,odd=0,even=0;
3.输入数据
- 通过cin输入二维数组的行数n和列数m。
- 再通过两层循环输入二维数组的每一个元素。
- 对于每一个输入的元素t,判断它是奇数还是偶数。
- 如果t是偶数(t % 2 == 0),则将even计数器加一。
- 如果t是奇数,则将odd计数器加一。
//三、数据输入
cin>>n>>m;
for(int i=0;i<n;++i){
for(int j=0;j<m;++j){
cin>>t;
//四、数据计算
if(t%2==0){
++even;
}else{
++odd;
}
}
}
5.输出
- 输出奇数和偶数的数量,中间用空格隔开。
//五、输出结果
cout<<odd<<" "<<even;
完整代码如下:
#include <bits/stdc++.h>
using namespace std;
int main() {
// 问题分析
// 已知条件:一个 n 行 m 列的二维数组。
// 求解:统计出这个二维数组中奇数和偶数分别有多少个。
// 关系:通过遍历数组中的每个元素,统计奇数和偶数的数量。
// 数据定义
int n, m, t; // n 表示行数,m 表示列数,t 表示当前读入的数字
int odd = 0, even = 0; // odd 用于计数奇数的数量,even 用于计数偶数的数量
// 数据输入
cin >> n >> m; // 输入二维数组的行数 n 和列数 m
for (int i = 0; i < n; ++i) { // 遍历每一行
for (int j = 0; j < m; ++j) { // 遍历每一列
cin >> t; // 读入当前位置的数字
// 数据计算
if (t % 2 == 0) { // 如果是偶数
++even; // 偶数计数器加一
} else { // 如果是奇数
++odd; // 奇数计数器加一
}
}
}
// 输出结果
cout << odd << " " << even; // 输出奇数和偶数的数量
return 0; // 程序正常结束
}
三、感谢
如若本文对您的学习或工作有所启发和帮助,恳请您给予宝贵的支持——轻轻一点,为文章点赞;若觉得内容值得分享给更多朋友,欢迎转发扩散;若认为此篇内容具有长期参考价值,敬请收藏以便随时查阅。
每一次您的点赞、分享与收藏,都是对我持续创作和分享的热情鼓励,也是推动我不断提供更多高质量内容的动力源泉。期待我们在下一篇文章中再次相遇,共同攀登知识的高峰!
欢迎关注本专栏《C++从零基础到信奥赛入门级(CSP-J)》