1. 程式人生 > 其它 >AT2686 [ARC080A] 4-adjacent 題解

AT2686 [ARC080A] 4-adjacent 題解

AT2686 [ARC080A] 4-adjacent 題解

Content

給定一個長度為 \(n\) 的數列 \(a\),請將其重新排列,使得 \(\forall i\in[1,n-1]\),都有 \(4\mid (a_i\cdot a_{i+1})\),或者報告不存在。

資料範圍:\(2\leqslant n\leqslant 10^5\)\(1\leqslant a_i\leqslant 10^9\)

Solution

簡單的分類討論題。

我們不妨在讀入的時候統計出奇數的數量 \(\textit{cnt}_1\)\(4\) 的倍數的數量 \(\textit{cnt}_2\),然後:

i) 當 \(\textit{cnt}_1+\textit{cnt}_2\neq n\)

時,此時除了奇數和 \(4\) 的倍數以外,還有部分不是 \(4\) 的倍數的偶數,那麼它們一定只可能是 \(2\) 的倍數而不可能是 \(2^k(k\geqslant 2)\) 的倍數。因此我們在這裡考慮把這些數放到後面去,前面的留給奇數和 \(4\) 的倍數,以使得相鄰兩個數相乘得到 \(4\) 的倍數。
那麼前面的奇數和 \(4\) 的倍數怎麼放呢?我們可以考慮交叉放,即先放奇數再放 \(4\) 的倍數再放奇數……或者先放 \(4\) 的倍數再放奇數再放 \(4\) 的倍數……那麼最優方案下先放哪個呢?不難發現如果先放奇數的話,最壞情況下當 \(\textit{cnt}_1=\textit{cnt}_2\)
時,是可以構造出合法的排列的。否則就不行。
因此,在 i) 的情況下,只需要滿足 \(\textit{cnt}_1\leqslant\textit{cnt}_2\),就能夠構造出合法的排列。

ii) 當 \(\textit{cnt}_1+\textit{cnt}_2=n\) 時,此時最壞的情況無非就是 \(\textit{cnt}_1=\textit{cnt}_2+1\) 時,先全部放奇數,然後再在每兩個奇數的中間放 \(4\) 的倍數,即可滿足要求。
因此,在 ii) 的情況下,只需要滿足 \(\textit{cnt}_1\leqslant\textit{cnt}_2+1\),就能夠構造出合法的序列。

根據其實際情況分類判斷一下就可以了。

Code

int n, a[100007], cntodd, cntfour;

int main() {
	n = Rint;
	F(int, i, 1, n) {
		a[i] = Rint;
		if(a[i] % 2) cntodd++;
		else if(!(a[i] % 4)) cntfour++;
	}
	return cntodd <= cntfour || (cntodd + cntfour == n && cntodd - cntfour <= 1) ? Yes : No, 0;
}