第五屆藍橋杯Java B——矩陣翻硬幣
小明先把硬幣擺成了一個 n 行 m 列的矩陣。
隨後,小明對每一個硬幣分別進行一次 Q 操作。
對第x行第y列的硬幣進行 Q 操作的定義:將所有第 ix 行,第 j y 列的硬幣進行翻轉。
其中i和j為任意使操作可行的正整數,行號和列號都是從1開始。
當小明對所有硬幣都進行了一次 Q 操作後,他發現了一個奇蹟——所有硬幣均為正面朝上。
小明想知道最開始有多少枚硬幣是反面朝上的。於是,他向他的好朋友小M尋求幫助。
聰明的小M告訴小明,只需要對所有硬幣再進行一次Q操作,即可恢復到最開始的狀態。然而小明很懶,不願意照做。於是小明希望你給出他更好的方法。幫他計算出答案。
【資料格式】
輸入資料包含一行,兩個正整數 n m,含義見題目描述。
輸出一個正整數,表示最開始有多少枚硬幣是反面朝上的。
【樣例輸入】
2 3
【樣例輸出】
1
【資料規模】
對於10%的資料,n、m <= 10^3;
對於20%的資料,n、m <= 10^7;
對於40%的資料,n、m <= 10^15;
對於10%的資料,n、m <= 10^1000(10的1000次方)。
資源約定:
峰值記憶體消耗(含虛擬機器) < 256M
CPU消耗< 2000ms
思路
最後一道程式設計題,還是有點水平的,還是要好好寫寫題解
考慮一般的情況,對於某個矩陣位置$(x,y)$反向回推,$(x,y)$初始狀態是正面向上的,經過若干次翻轉行,列以後導致他變成反面向上,很明顯,這個"若干次",一定是奇數次
$x$的因子假設為$x_1,x_2...x_p$,$y$的因子假設為$y_1,y_2...y_q$,這些因子兩兩任意組合就能構成$p\times q$個點。
也就是說,如果$x$的因子個數$p$乘以$y$的因子個數$q$為奇數,那麼$(x,y)$就是反面朝上的了。因為只有奇數$\times$奇數$=$奇數,所以要求$x$的因子個數和$y$的因子個數必須都為奇數。又因為只有完全平方數的因子個數為奇數 ,所以問題就轉化成了,判斷$x$和$y$是否同時是完全平方數。到這裡已經可以拿20%的分了
由於$n$和$m$的範圍太大,所以不能每個座標去列舉是否是完全平方數。這裡就要用到另一個重要的性質:$1-n$內完全平方數的個數為$\sqrt{n}$個