PAT-B 1068. 萬綠叢中一點紅(20)

傳送門

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;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容