傳送門
https://pintia.cn/problem-sets/994805260223102976/problems/994805265579229184
題目
對于計算機而言,顏色不過是像素點對應(yīng)的一個24位的數(shù)值?,F(xiàn)給定一幅分辨率為MxN的畫,要求你找出萬綠叢中的一點紅,即有獨一無二顏色的那個像素點,并且該點的顏色與其周圍8個相鄰像素的顏色差充分大。
輸入格式:
輸入第一行給出三個正整數(shù),分別是M和N(<= 1000),即圖像的分辨率;以及TOL,是所求像素點與相鄰點的顏色差閾值,色差超過TOL的點才被考慮。隨后N行,每行給出M個像素的顏色值,范圍在[0, 224)內(nèi)。所有同行數(shù)字間用空格或TAB分開。
輸出格式:
在一行中按照“(x, y): color”的格式輸出所求像素點的位置以及顏色值,其中位置x和y分別是該像素在圖像矩陣中的列、行編號(從1開始編號)。如果這樣的點不唯一,則輸出“Not Unique”;如果這樣的點不存在,則輸出“Not Exist”。
輸入樣例1:
8 6 200
由于這里不直觀,直接放個表格上來:
| 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
|---|---|---|---|---|---|---|---|
| 65280 | 65280 | 65280 | 16711479 | 65280 | 65280 | 65280 | 65280 |
| 16711479 | 65280 | 65280 | 65280 | 16711680 | 65280 | 65280 | 65280 |
| 65280 | 65280 | 65280 | 65280 | 65280 | 65280 | 165280 | 165280 |
| 65280 | 65280 | 16777015 | 65280 | 65280 | 165280 | 65480 | 165280 |
| 16777215 | 16777215 | 16777215 | 16777215 | 16777215 | 16777215 | 16777215 | 16777215 |
輸出樣例1:
(5, 3): 16711680
輸入樣例2:
4 5 2
0 0 0 0
0 0 3 0
0 0 0 0
0 5 0 0
0 0 0 0
輸出樣例2:
Not Unique
輸入樣例3:
3 3 5
1 2 3
3 4 5
5 6 7
輸出樣例3:
Not Exist
分析
很煩的一題,改了好多次都沒過,參考了各種代碼,最后才知道坑在哪里,下面讓我來簡單說一下。
首先要寫個判斷“一點紅”的函數(shù),我那個方法寫的很直觀很好懂(其實是有點low,哈哈人艱不拆)。
接著要有一個判重的方法來判斷數(shù)字是否重復(fù),如果不重復(fù)并且滿足“一點紅”的條件才符合。
此條見題中原句:
對于計算機而言,顏色不過是像素點對應(yīng)的一個24位的數(shù)值?,F(xiàn)給定一幅分辨率為MxN的畫,要求你找出萬綠叢中的一點紅,即有獨一無二顏色的那個像素點,并且該點的顏色與其周圍8個相鄰像素的顏色差充分大。
覺得好坑是嗎?是的,跟上我的腳步,后面還有更坑的。
代碼寫到目前為止,我天真的以為應(yīng)該就可以A了,但是我萬萬沒想到的是,問題出在了我的遍歷方法。
剛才的題目中提到“周圍8個相鄰像素的顏色”,所以我很自然認為,最上、最左、最右、最下這四列,由于附近的像素構(gòu)成不了8個,故舍去,但是這樣的結(jié)果是兩個檢查點通過不了。
參考了網(wǎng)上各類代碼后,發(fā)現(xiàn)成功的解法與我的解法的差別就在于對四個邊元素的驗證,只要對其進行驗證,題目就能A掉,于是我給輸入的數(shù)組四周補上了0,然后將四個邊上的數(shù)也進行驗證后,就通過了這道題,類似下圖。
0 0 0 0 0
0 x x x 0
0 x x x 0
0 x x x 0
0 0 0 0 0
這就是我解題時遇到的各種問題,希望能解決大家的疑問。
源代碼
//C/C++實現(xiàn)
#include <iostream>
#include <vector>
#include <cmath>
#include <map>
using namespace std;
bool isRed(int i, int j, vector<vector<int> > v, int tol){
if (abs(v[i - 1][j - 1] - v[i][j]) <= tol){ // 左上角
return false;
}
if (abs(v[i][j - 1] - v[i][j]) <= tol){ // 上
return false;
}
if (abs(v[i + 1][j - 1] - v[i][j]) <= tol){ // 右上角
return false;
}
if (abs(v[i + 1][j] - v[i][j]) <= tol){ // 右
return false;
}
if (abs(v[i + 1][j + 1] - v[i][j]) <= tol){ // 右下角
return false;
}
if (abs(v[i][j + 1] - v[i][j]) <= tol){ // 下
return false;
}
if (abs(v[i - 1][j + 1] - v[i][j]) <= tol){ // 左下角
return false;
}
if (abs(v[i - 1][j] - v[i][j]) <= tol){ // 左
return false;
}
return true;
}
vector<vector<int> > v;
int main(){
int m, n, tol;
scanf("%d %d %d", &m, &n, &tol);
// n行m列二維數(shù)組
v.resize(n + 2);
for (int i = 0; i < n + 2; ++i){
v[i].resize(m + 2);
}
map<int, int> isRepeat;
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j){
scanf("%d", &v[i][j]);
++isRepeat[v[i][j]];
}
}
int cnt = 0;
int resI, resJ;
for (int i = 1; i <= n; ++i){
for (int j = 1; j <= m; ++j){
if (isRepeat[v[i][j]] == 1){ // 只出現(xiàn)過一次
if (isRed(i, j, v, tol)){
++cnt;
resI = i;
resJ = j;
if (cnt == 2){
break;
}
}
}
}
if (cnt == 2){
break;
}
}
if (cnt == 0){
printf("Not Exist\n");
}
else if (cnt == 1){
printf("(%d, %d): %d\n", resJ, resI, v[resI][resJ]);
}
else if (cnt == 2){
printf("Not Unique\n");
}
return 0;
}