PAT Basic 1068. 萬綠叢中一點(diǎn)紅(20)(C語言實(shí)現(xiàn))

我的PAT系列文章更新重心已移至Github绣夺,歡迎來看PAT題解的小伙伴請(qǐng)到Github Pages瀏覽最新內(nèi)容鹿驼。此處文章目前已更新至與Github Pages同步鸣剪。歡迎star我的repo零蓉。

題目

對(duì)于計(jì)算機(jī)而言卿嘲,顏色不過是像素點(diǎn)對(duì)應(yīng)的一個(gè) 24 位的數(shù)值】妒龋現(xiàn)給定一幅分辨率為 M\times N
的畫宿百,要求你找出萬綠叢中的一點(diǎn)紅,即有獨(dú)一無二顏色的那個(gè)像素點(diǎn)洪添,并且該點(diǎn)的顏色與其周圍 8 個(gè)相鄰像素的顏色差充分大垦页。

輸入格式:

輸入第一行給出三個(gè)正整數(shù),分別是 MN\le 1000)干奢,即圖像的分辨率痊焊;以及 TOL,是所求像素點(diǎn)與相鄰點(diǎn)的顏色差閾值忿峻,色差超過
TOL 的點(diǎn)才被考慮薄啥。隨后 N 行,每行給出 M 個(gè)像素的顏色值逛尚,范圍在 [0, 2^{24}) 內(nèi)垄惧。所有同行數(shù)字間用空格或 TAB 分開。

輸出格式:

在一行中按照 (x, y): color 的格式輸出所求像素點(diǎn)的位置以及顏色值绰寞,其中位置 xy 分別是該像素在圖像矩陣中的列到逊、行編號(hào)(從
1 開始編號(hào))铣口。如果這樣的點(diǎn)不唯一,則輸出 Not Unique觉壶;如果這樣的點(diǎn)不存在脑题,則輸出 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

思路

在這道題上我好像想多了铜靶,當(dāng)然也有可能陳越姥姥想少了(怎么可能叔遂,不可能的)。

首先就是争剿,“顏色差” 是什么已艰?網(wǎng)上其他人的做法99%(可能100%)都是直接把兩個(gè)顏色的值相減,結(jié)果的整數(shù)就是顏色差了蚕苇。
而我參考了Wiki: Color difference哩掺,
將(R, G, B)三維顏色空間的“距離”作為顏色差,這也是很合理的捆蜀。比如65280疮丛,也就是#00FF00,是綠色辆它,
而65279誊薄,#00FEFF,是青色锰茉,兩者在整數(shù)大小上相差1呢蔫,但是顏色有很大區(qū)別。幸好(或許也是不幸)在測(cè)試用例沒有使用上面這樣的例子飒筑,
我的測(cè)試結(jié)果和大家都是一樣的片吊。

然后就是大家都遇到的難(keng)點(diǎn):

  • 第一個(gè)難(keng)點(diǎn):

要求你找出萬綠叢中的一點(diǎn)紅,即有獨(dú)一無二顏色的那個(gè)像素點(diǎn)

解讀:需要這個(gè)顏色在整幅圖中只出現(xiàn)一次协屡。

  • 第二個(gè)難(keng)點(diǎn):雖然題目說

該點(diǎn)的顏色與其周圍8個(gè)相鄰像素的顏色差充分大俏脊。

但是題目還是設(shè)置了處于邊界的滿足“條件”的點(diǎn),所以說這又是一個(gè)題目敘述不清楚的案例(好多受害者)肤晓。

應(yīng)對(duì)這個(gè)問題目前看到的代碼中有兩個(gè)解決方案爷贫,一是加入邊界特殊情況的檢測(cè),二是在題目數(shù)據(jù)的周圍加一圈0补憾。
第一個(gè)方案沒有問題漫萄。第二個(gè)方案我覺得是有問題的,如圖片的左上角有這樣的數(shù)據(jù):

#000001 #0000FF ......
#0000FF #0000FF ......
......  ......  ......

假設(shè)顏色#000001在圖片只出現(xiàn)了這一次盈匾,這樣這個(gè)點(diǎn)應(yīng)該符合要求腾务。但是周圍加上0就變成了

#000000 #000000 #000000 ......
#000000 #000001 #0000FF ......
#000000 #0000FF #0000FF ......
......  ......  ......  ......

不管顏色差是怎么算的,這個(gè)中間的#000001都是不能被檢測(cè)出來的削饵。但是又很幸運(yùn)地岩瘦,我看使用這個(gè)方法的代碼也都通過了未巫。
我能說什么呢 :)

P.S.

關(guān)于代碼優(yōu)化:這個(gè)代碼運(yùn)行時(shí)間好長(160+ms),應(yīng)該是判斷顏色唯一太耗時(shí)了担钮,相當(dāng)于O(N2*M2)橱赠,
或許改為用另一個(gè)排序好的列表查找會(huì)好很多(預(yù)計(jì)時(shí)間復(fù)雜度為M*N*log(M*N))尤仍。

更新:上面的判斷竟然是錯(cuò)的箫津,我在本地測(cè)試了上述方案,使用最多的數(shù)據(jù)1000*1000宰啦,排序加查找竟然比原來的方案耗時(shí)多一個(gè)數(shù)量級(jí)
~~~o(>﹏<)o苏遥。之前的方案從文件讀取用了0.2秒,但是查找只用了0.04秒(其中iUnique函數(shù)只有0.02秒I哪!)田炭。
新的方案qsort用了0.2秒,查找(使用了bsearch)用了0.3秒漓柑!這不科學(xué) (ㄒoㄒ) (難道是被stdlib坑了教硫?)
(證明瓶頸在數(shù)據(jù)讀取上,那運(yùn)行時(shí)間長的鍋我就不背了)

代碼

最新代碼@github辆布,歡迎交流

#include <stdio.h>

#define SQR(X) ((X)*(X))
#define R(COLOR) ((COLOR & 0XFF0000) >> 16)
#define G(COLOR) ((COLOR & 0X00FF00) >> 8)
#define B(COLOR) (COLOR & 0X0000FF)
#define D(C1, C2) (SQR(R(C1) - R(C2)) + SQR(G(C1) - G(C2)) +  SQR(B(C1) - B(C2)))

int iUnique(int array[][1000], int x, int y, int x0, int y0)
{
    for(int i = 0; i < x; i++)
        for(int j = 0; j < y; j++)
            if(array[i][j] == array[x0][y0] && !(i == x0 && j == y0))
                return 0;
    return 1;
}

int main()
{
    int M, N, TOL;
    scanf("%d %d %d", &M, &N, &TOL);

    int fig[1000][1000];
    for(int i = 0; i < N; i++)
        for(int j = 0; j < M; j++)
            scanf("%d", &fig[i][j]);

    int count = 0, M0, N0;
    for(int i = 0; i < N; i ++)
        for (int j = 0; j < M; j++)
            if((i > 0 && j > 0 ? D(fig[i][j], fig[i - 1][j - 1]) > SQR(TOL) : 1)
            && (i > 0          ? D(fig[i][j], fig[i - 1][j    ]) > SQR(TOL) : 1)
            && (i > 0 && j < M ? D(fig[i][j], fig[i - 1][j + 1]) > SQR(TOL) : 1)
            && (         j > 0 ? D(fig[i][j], fig[i    ][j - 1]) > SQR(TOL) : 1)
            && (         j < M ? D(fig[i][j], fig[i    ][j + 1]) > SQR(TOL) : 1)
            && (i < N && j > 0 ? D(fig[i][j], fig[i + 1][j - 1]) > SQR(TOL) : 1)
            && (i < N          ? D(fig[i][j], fig[i + 1][j    ]) > SQR(TOL) : 1)
            && (i < N && j < M ? D(fig[i][j], fig[i + 1][j + 1]) > SQR(TOL) : 1)
            && iUnique(fig, N, M, i, j))
            {
                count++;
                N0 = i;
                M0 = j;
            }

    if(count == 0)  printf("Not Exist");
    if(count == 1)  printf("(%d, %d): %d", M0 + 1, N0 + 1, fig[N0][M0]);
    if(count >= 2)  printf("Not Unique");

    return 0;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末瞬矩,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子锋玲,更是在濱河造成了極大的恐慌景用,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評(píng)論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件惭蹂,死亡現(xiàn)場(chǎng)離奇詭異伞插,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)盾碗,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門媚污,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人廷雅,你說我怎么就攤上這事耗美。” “怎么了榜轿?”我有些...
    開封第一講書人閱讀 168,766評(píng)論 0 361
  • 文/不壞的土叔 我叫張陵幽歼,是天一觀的道長。 經(jīng)常有香客問我谬盐,道長甸私,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評(píng)論 1 299
  • 正文 為了忘掉前任飞傀,我火速辦了婚禮皇型,結(jié)果婚禮上诬烹,老公的妹妹穿的比我還像新娘。我一直安慰自己弃鸦,他們只是感情好绞吁,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著唬格,像睡著了一般家破。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上购岗,一...
    開封第一講書人閱讀 52,457評(píng)論 1 311
  • 那天汰聋,我揣著相機(jī)與錄音,去河邊找鬼喊积。 笑死烹困,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的乾吻。 我是一名探鬼主播髓梅,決...
    沈念sama閱讀 40,999評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼绎签!你這毒婦竟也來了枯饿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,914評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤辜御,失蹤者是張志新(化名)和其女友劉穎鸭你,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體擒权,經(jīng)...
    沈念sama閱讀 46,465評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡袱巨,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評(píng)論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了碳抄。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片愉老。...
    茶點(diǎn)故事閱讀 40,675評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖剖效,靈堂內(nèi)的尸體忽然破棺而出嫉入,到底是詐尸還是另有隱情,我是刑警寧澤璧尸,帶...
    沈念sama閱讀 36,354評(píng)論 5 351
  • 正文 年R本政府宣布咒林,位于F島的核電站,受9級(jí)特大地震影響爷光,放射性物質(zhì)發(fā)生泄漏垫竞。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望欢瞪。 院中可真熱鬧活烙,春花似錦、人聲如沸遣鼓。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽骑祟。三九已至回懦,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間曾我,已是汗流浹背粉怕。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評(píng)論 1 274
  • 我被黑心中介騙來泰國打工健民, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抒巢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,091評(píng)論 3 378
  • 正文 我出身青樓秉犹,卻偏偏與公主長得像蛉谜,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子崇堵,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評(píng)論 2 360

推薦閱讀更多精彩內(nèi)容