藍橋杯 演算法訓練 審美課

2022-07-03 16:06:16 字數 2848 閱讀 2850

時間限制:1.0s   記憶體限制:256.0mb

問題描述

《審美的歷程》課上有n位學生,帥老師展示了m幅畫,其中有些是梵谷的作品,另外的都出自五歲小朋友之手。老師請同學們分辨哪些畫的作者是梵谷,但是老師自己並沒有答案,因為這些畫看上去都像是小朋友畫的……老師只想知道,有多少對同學給出的答案完全相反,這樣他就可以用這個資料去揭穿披著皇帝新衣的抽象藝術了(支援帥老師^_^)。

答案完全相反是指對每一幅畫的判斷都相反。

輸入格式

第一行兩個數n和m,表示學生數和圖畫數;

接下來是乙個n*m的01矩陣a:

如果aij=0,表示學生i覺得第j幅畫是小朋友畫的;

如果aij=1,表示學生i覺得第j幅畫是梵谷畫的。

輸出格式

輸出乙個數ans:表示有多少對同學的答案完全相反。

樣例輸入

3 21 0

0 11 0

樣例輸出

2樣例說明

同學1和同學2的答案完全相反;

同學2和同學3的答案完全相反;

所以答案是2。

資料規模和約定

對於50%的資料:n<=1000;

對於80%的資料:n<=10000;

對於100%的資料:n<=50000,m<=20。

使用暴力法只得了70分,最後三個測試用力不通過,需要使用二進位制儲存的思路:

將每個學生的答案用陣列a[i]以二進位制的形式儲存(二進位制011對應的是3)。則答案相同的學生在陣列a[i]存的值是相同的。

陣列res[ a[i] ]用於儲存每種答案的人數。例如,假設res[3]=10,即有10個人答案相同且答案都為3 (十進位制3對應的二進位制為011)。

按行遍歷,按位取反,與取反後的答案相同的,即為題目要求的完全相反的答案。

最後sum/2是因為重複計算了,除以2之後才是「有多少對同學」。

注意

乍一看,取反不是「~」嗎,為什麼用的異或運算子「^」?

異或運算子的規則是:相反為1,相同為0,即:0^0=0, 1^0=1, 0^1=1, 1^1=0

所以無論1還是0,與1異或就實現了取反操作。故可以實現按位取反

源**:

1 #include2

using

namespace

std;34

int a[50000]; //

最大輸入50000個學生

5int res[1048580]=; //

一共20副畫圖數,最多有2的20次方來儲存 ,類似於篩選法

6int sum=0; //

計算最終結果 78

intmain()

921 res[a[i]]++;22}

2324

int max=(1

<1; //

構造m位全為1的二進位制,如3位,向左移動3位就為8,8-1=7的二進位制為111 ,剛好為三位

25for(int i=0;i)26

3031 cout<2; //

迴圈時候每個數d

32//

fclose(stdin);

33return0;

34 }

思路2:異或運算和map

用二進位制表示每位同學的回答。(m<=20;2^20 在int的範圍內)。

相反的答案用二進位制與m個1,1,1.....1(即2^m-1)的數maxn取異或即可。(如 01 == 1 ,10 == 2,2^3 == 1(異或),1^3 == 2 )

因為map預設是按key值從小到大排序的,則可以直接在遍歷map中取0~maxn/2即可。

設m個1,1,1.....1(即2^m-1)的數為maxn,mid = maxn/2; 通過列舉你會發現 maxn^x = maxn-x = y (x,y屬於[0,maxn]),(maxn與x逐位取異或 實際就是逐位做減法,因為maxn全為1(1>=),不存在減法借位的),如(111-010 = 101 = 111^010),則[0,mid]的乙個數x與maxn取異的值y一定在(mid,maxn]中。如(maxn = 7, 7^0=7 - 0 = 7、7^1=7-1=6、7^2=7-2=5).

如果你遍歷了map中的[0~mid]那麼後面的就不需要再遍歷了,因為後面map中能與[0~mid]匹配的值肯定已經被匹配過了。此步驟可要可不要,不會影響實際的通過。

1 #include 2

using

namespace

std;34

intmain()

523 ans[num]++; //

將每個對應的二進位制數key的value+1,value預設為0

24}

2526

int sum=0,maxn=(1

<1,mid=maxn/2

; 27

28for(map::iterator it=ans.begin();it!=ans.end();++it)

2935

int temp=x^maxn; ///

/構造m位全為1的二進位制,如3位,向左移動3位就為8,8-1=7的二進位制為111 ,剛好為三位

36 sum+=ans[temp]*it->second; //

需要將當前的相同的個數和與他取反的數的個數相乘才是有多少個 37}

38 cout<3940

//fclose(stdin);

41return0;

42 }

藍橋杯 演算法訓練 審美課

借鑑出處 自己暴力模擬得了70分 自己太菜 用處 加深對map的理解 問題描述 審美的歷程 課上有n位學生,帥老師展示了m幅畫,其中有些是梵谷的作品,另外的都出自五歲小朋友之手。老師請同學們分辨哪些畫的作者是梵谷,但是 老師自己並沒有答案,因為這些畫看上去都像是小朋友畫的 老師只想知道,有多少對同學...

藍橋杯 演算法訓練 審美課

將每一行的數字用二進位制數儲存在陣列 a i 中,累加 a i 出現的個數儲存在 b a i 中。a i 取反可得到 a i 完全相反的答案。取反可將 a i 與 1 1 1 1 1 1.m個1 異或,答案相同。總數 2即為答案。注意 是按位移中的左位移,向左移動幾位就是乘以2的幾次方。參考自 in...

藍橋杯演算法訓練 審美課

問題描述 審美的歷程 課上有n位學生,帥老師展示了m幅畫,其中有些是梵谷的作品,另外的都出自五歲小朋友之手。老師請同學們分辨哪些畫的作者是梵谷,但是老師自己並沒有答案,因為這些畫看上去都像是小朋友畫的 老師只想知道,有多少對同學給出的答案完全相反,這樣他就可以用這個資料去揭穿披著皇帝新衣的抽象藝術了...