數學,規律,構造類問題
題意,就是以任意一個點為中心,交換它左右兩個點的位置。
一開始想這題,有個地方錯了,所以一直想不到,就是把所有黑子當成一樣的,白子當成一樣,這樣想也不是說錯,但是這樣想會限制了思維
然後換一種思維,給所有棋子按1到n編號,就算顏色相同,編號也不同,是不同的棋子。
然後我們看看交換的時候會發生什麼事情
以點a為中心,那麼a-1和a+1發生交換,那麼也就是說,編號a-1的點去了a+1的位置,如果繼續交換的話,它還可以去到a+3,a+5……的位置,這裡有一個突破點就是,它所在的位置的奇偶性不行,如果它一開始就在奇數的位置,無論怎麼交換它還是在奇數位置,偶數亦然。
但!不要這麼輕易下結論,看看在結尾成環的地方會發生什麼
如果以1為中心,那麼n和2就可以交換位置
如果以n為中心,n-1和1就可以交換位置
這時候如果主要到了n的奇偶性的話,就能發現問題
如果n是奇數:
以1為中心的時候,n和2交換,那麼也就是說編號為n的點,原本在奇數的位置,現在去了2,就在偶數位置了,而2號點本來在2的位置現在去了n位置,位置的奇偶性也發生了變化
同樣的,如果以n為中心,交換n-1和1,它們所在的位置的奇偶性也會發生變化
結合上面的,如果不在借口處,交換,一個點所在的位置的奇偶性不變,如果在介面處交換,位置的奇偶性就會發生變化。那麼,一個點其實能去到任何它想去到的位置?對的沒錯!
一個點如果在偶數位,那麼不斷交換,它始終只能去到偶數位,但是到了介面處,卻改變了它位置的奇偶性,下一輪它就去到了奇數位置,在這一輪中它又始終在奇數位置…………依次不斷迴圈下去!所以很幸運的,這個點,只要它願意,只要迴圈次數足夠多,那麼它能去到任何一個它想去到的位置
如果n是偶數:
以1為中心,n和2交換,會發現n和2都是偶數,即使交換了,它們所在位置的奇偶性不會發生變化
以n為中心,n-1和1交換,會發現n-1和1都是奇數,即使交換了,它們所在的位置的奇偶性不會發生變化
所以對於n是偶數的情況則沒那麼幸運了,一個點一開始在偶數位置的話,無論怎麼交換,即使到了介面處繼續交換,都不能改變它所在位置的奇偶性。一開始的位置就是奇數亦然
有了上面這兩條很重要結論,我們的問題其實變為了一個構造類問題,並且僅僅是判斷這個構造能否成功
結論1:如果序列長度為奇數,對於序列中的任意一個點,它能去到任何位置
結論2:如果序列長度為偶數,對於序列中一開始就在奇數位置的點,它能去到任意奇數位置但去不到偶數位置,對於一開始就在偶數位置的點,它能去到任何偶數位置但去不到奇數位置
我們構造的目的是將所有黑色點聚集在一起:
當n為奇數的時候,這太容易了,因為我們能將任意一個黑色點移動到我們想讓它去的地方,所以要它們聚集在一起,那是一定能做到的,所以n為奇數,一定為YES
當n為偶數的時候,如果黑色點一開始就在偶數位置,我們能將它移到任意偶數位置,奇數亦然。所以我們只要保證,一開始,處在奇數位置的黑點和處在偶數位置的黑點的個數相差不超過1,那麼就能聚集在一起。因為如果個數相差超過了1,那麼必然必然導致一些黑點能聚集在一起,但是另一些黑點則隔著放,因為他們所在位置的奇偶性不能改變!
#include <iostream>using namespace std;inline int abs(int a ,int b){ return a-b > 0 ? a-b : b-a;}int main(){ int cas,n,a,b,x; cin >> cas; while(cas--) { cin >> n; a = b = 0; for(int i=1; i<=n; i++) { cin >> x; if(x && i&1) a++; else if(x && !(i&1)) b++; } if(n&1 || abs(a,b)<=1) cout << "YES" << endl; else cout << "NO" << endl; } return 0;}