题目:给定一幅分辨率为 M×N 的画,要求你找出万绿丛中的一点红,即有独一无二颜色的那个像素点,并且该点的颜色与其周围 8 个相邻像素的颜色差充分大。
输入格式:
第一行:M、N、TOL(分辨率MxN,色差阈值TOL)
随后N行,每行给出M个像素值
输出格式:
在一行中按照 (x, y): color 的格式输出所求像素点的位置以及颜色值
其中位置 x 和 y 分别是该像素在图像矩阵中的列、行编号(从 1 开始编号)。
如果这样的点不唯一,则输出
Not Unique
;如果这样的点不存在,则输出Not Exist
。
思路:用map记录不同颜色值出现的次数,用二维矩阵保存像素值,依次对每个像素点进行判断其是否满足题目要求。
代码:
#include<iostream>
#include<map>
using namespace std;
int main(){
int m,n,tol;cin >> m >> n >> tol;
map<int,int> mp; // 记录各颜色值出现次数
int ** arr = new int*[n];
for(int i = 0 ; i < n ; i ++)
arr[i] = new int[m];
// 保存图像
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j < m ; j ++){
cin >> arr[i][j];
// 记录出现的颜色值
if(mp.find(arr[i][j]) != mp.end())
mp[arr[i][j]] ++;
else
mp[arr[i][j]] = 1;
}
}
int count = 0; // 记录特定点的个数
int x = 0 , y = 0;
for(int i = 0 ; i < n ; i ++){
for(int j = 0 ; j < m ; j ++){
int a = arr[i][j];
// 颜色值不唯一
if(mp[a] > 1)
continue;
// 色差与上面的三个点比较
if(i-1 >= 0){ // arr[i-1][j-1] , arr[i-1][j] , arr[i-1][j+1]
if(abs(a-arr[i-1][j]) <= tol || (j-1 >= 0 && abs(a-arr[i-1][j-1]) <= tol) || (j+1 < m && abs(a-arr[i-1][j+1]) <= tol))
continue;
}
// 色差与中间的两个点比较
// arr[i][j-1] , arr[i][j+1]
if(j-1 >= 0 && abs(a-arr[i][j-1]) <= tol)
continue;
if(j+1 < m && abs(a-arr[i][j+1]) <= tol)
continue;
// 色差与下面的三个点比较
if(i+1 < n){ // arr[i+1][j-1] , arr[i+1][j] , arr[i+1][j+1]
if(abs(a-arr[i+1][j]) <= tol || (j-1 >= 0 && abs(a-arr[i+1][j-1]) <= tol) || (j+1 < m && abs(a-arr[i+1][j+1]) <= tol))
continue;
}
count ++;
if(count > 1){
cout << "Not Unique" << endl;
return 0;
}else{
x = j + 1;
y = i + 1;
}
}
} // for
if(count == 0)
cout << "Not Exist" << endl;
else
cout << "(" << x <<", " << y << "): " << arr[y-1][x-1] << endl;
return 0;
}