傳送門
https://pintia.cn/problem-sets/994805260223102976/problems/994805265579229184
題目
對(duì)于計(jì)算機(jī)而言,顏色不過是像素點(diǎn)對(duì)應(yīng)的一個(gè)24位的數(shù)值×ぬ叮現(xiàn)給定一幅分辨率為MxN的畫特碳,要求你找出萬綠叢中的一點(diǎn)紅入篮,即有獨(dú)一無二顏色的那個(gè)像素點(diǎn)进副,并且該點(diǎn)的顏色與其周圍8個(gè)相鄰像素的顏色差充分大民轴。
輸入格式:
輸入第一行給出三個(gè)正整數(shù)解滓,分別是M和N(<= 1000)咱士,即圖像的分辨率立由;以及TOL轧钓,是所求像素點(diǎn)與相鄰點(diǎn)的顏色差閾值,色差超過TOL的點(diǎn)才被考慮锐膜。隨后N行毕箍,每行給出M個(gè)像素的顏色值,范圍在[0, 224)內(nèi)道盏。所有同行數(shù)字間用空格或TAB分開而柑。
輸出格式:
在一行中按照“(x, y): color”的格式輸出所求像素點(diǎn)的位置以及顏色值,其中位置x和y分別是該像素在圖像矩陣中的列荷逞、行編號(hào)(從1開始編號(hào))牺堰。如果這樣的點(diǎn)不唯一,則輸出“Not Unique”颅围;如果這樣的點(diǎn)不存在,則輸出“Not Exist”恨搓。
輸入樣例1:
8 6 200
由于這里不直觀院促,直接放個(gè)表格上來:
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
分析
很煩的一題,改了好多次都沒過斧抱,參考了各種代碼常拓,最后才知道坑在哪里,下面讓我來簡(jiǎn)單說一下辉浦。
首先要寫個(gè)判斷“一點(diǎn)紅”的函數(shù)弄抬,我那個(gè)方法寫的很直觀很好懂(其實(shí)是有點(diǎn)low,哈哈人艱不拆)宪郊。
接著要有一個(gè)判重的方法來判斷數(shù)字是否重復(fù)掂恕,如果不重復(fù)并且滿足“一點(diǎn)紅”的條件才符合。
此條見題中原句:
對(duì)于計(jì)算機(jī)而言弛槐,顏色不過是像素點(diǎn)對(duì)應(yīng)的一個(gè)24位的數(shù)值“猛觯現(xiàn)給定一幅分辨率為MxN的畫,要求你找出萬綠叢中的一點(diǎn)紅乎串,即有獨(dú)一無二顏色的那個(gè)像素點(diǎn)店枣,并且該點(diǎn)的顏色與其周圍8個(gè)相鄰像素的顏色差充分大。
覺得好坑是嗎叹誉?是的鸯两,跟上我的腳步,后面還有更坑的长豁。
代碼寫到目前為止钧唐,我天真的以為應(yīng)該就可以A了,但是我萬萬沒想到的是蕉斜,問題出在了我的遍歷方法逾柿。
剛才的題目中提到“周圍8個(gè)相鄰像素的顏色”缀棍,所以我很自然認(rèn)為,最上机错、最左爬范、最右、最下這四列弱匪,由于附近的像素構(gòu)成不了8個(gè)青瀑,故舍去,但是這樣的結(jié)果是兩個(gè)檢查點(diǎn)通過不了萧诫。
參考了網(wǎng)上各類代碼后斥难,發(fā)現(xiàn)成功的解法與我的解法的差別就在于對(duì)四個(gè)邊元素的驗(yàn)證,只要對(duì)其進(jìn)行驗(yàn)證帘饶,題目就能A掉哑诊,于是我給輸入的數(shù)組四周補(bǔ)上了0,然后將四個(gè)邊上的數(shù)也進(jìn)行驗(yàn)證后及刻,就通過了這道題镀裤,類似下圖。
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
這就是我解題時(shí)遇到的各種問題缴饭,希望能解決大家的疑問暑劝。
源代碼
//C/C++實(shí)現(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;
}