CF1572B. Xor of 3
生活随笔
收集整理的這篇文章主要介紹了
CF1572B. Xor of 3
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
CF1572B. Xor of 3
題意:
給你個01序列,你有一種操作:每次選位置x,然后位置x,x+1,x+2的值變為三者的異或值。
現在要讓所有的數都等于0,請輸出存在的合法操作序列
題解:
首先如果有奇數個1,顯然是無解的
此時我們從第一個1開始考慮,成對考慮消除1(因為這樣異或為0),每次消除掉第一對1
如果兩個1之間有奇數個0:
比如10001,100000001,這種是可以直接消掉的
就拿100000001來說,假設第一個1的位置為x,那我們可以依次操作x,x+2,x+4,…,(x<長度),此時序列為:111111101,然后操作x+6就得到111111000,然后再倒著執行x+4,x+2…這樣就都變成0
如果兩個1之間有偶數個0
這樣是不能和上面一樣直接消除的,可以先全部變成1,然后需要借助外面的0,也就是如果左邊或右邊有一個0,就可以消除,否則無解
比如1001 -> 1111 假設 原序列是10010, 右邊有一個0, 那么現在11110可以消掉
實現起來挺麻煩的
代碼:
#include <bits/stdc++.h> #include <unordered_map> #define debug(a, b) printf("%s = %d\n", a, b); using namespace std; bool Handsome; typedef long long ll; typedef unsigned long long ull; typedef pair<int, int> PII; clock_t startTime, endTime; //Fe~Jozky const ll INF_ll= 1e18; const int INF_int= 0x3f3f3f3f; void read(){}; template <typename _Tp, typename... _Tps> void read(_Tp& x, _Tps&... Ar) {x= 0;char c= getchar();bool flag= 0;while (c < '0' || c > '9')flag|= (c == '-'), c= getchar();while (c >= '0' && c <= '9')x= (x << 3) + (x << 1) + (c ^ 48), c= getchar();if (flag)x= -x;read(Ar...); } template <typename T> inline void write(T x) {if (x < 0) {x= ~(x - 1);putchar('-');}if (x > 9)write(x / 10);putchar(x % 10 + '0'); } void rd_test(bool &Most) { #ifdef ONLINE_JUDGE #elseprintf("%.2lfMB\n",(&Most-&Handsome)/1024.0/1024.0);startTime = clock ();freopen("data.in", "r", stdin); #endif } void Time_test() { #ifdef ONLINE_JUDGE #elseendTime= clock();printf("\nRun Time:%lfs\n", (double)(endTime - startTime) / CLOCKS_PER_SEC); #endif } const int maxn=2e5+9; int a[maxn],nex[maxn]; vector<int>ans; int n; bool Most; int solve(int x){if(x>n)return 0;if(nex[x]==0)return 1;if(a[x]==0||(nex[x]-x-1)%2){//如果當前位置是0,或者中間有奇數個1 if(a[x]==0)x=nex[x];//找到后面最近1的位置 while(x){if((nex[x]-x-1)%2){//中間奇數個1,內部直接消 int i;for(i=x;i+2<nex[x];i+=2)ans.push_back(i);for(;i>=x;i-=2)ans.push_back(i);}else {//借助左邊的0消除 for(int i=x;i+2<nex[x];i+=2)ans.push_back(i);for(int i=x-1;i+2<=nex[x];i+=2)ans.push_back(i);}x=nex[nex[x]];//下下一個1的位置(因為1都是成對處理) }return 1; }else{//因為中間有偶數個1且當前不是0,所以需要判斷后面能否出現0 if(solve(nex[x]+1)){for(int i=x;i<nex[x]-2;i+=2)ans.push_back(i);for(int i=nex[x]+1;i-2>=x;i-=2)ans.push_back(i-2);return 1;}elsereturn 0; } } int main() {rd_test(Most);int t;read(t);while(t--){read(n);for(int i=1;i<=n;i++)read(a[i]);int las=0;int cnt=0;for(int i=n;i>=1;i--){nex[i]=las;if(a[i])//如果非0,記錄位置{las=i;cnt++;} }if(cnt%2)//如果奇數個1{printf("NO\n");continue; }ans.clear();if(solve(1)){printf("YES\n%d\n", ans.size());for(int i=0; i<ans.size(); i++) {printf("%d ", ans[i]);}printf("\n");} else printf("NO\n");}//Time_test(); }總結
以上是生活随笔為你收集整理的CF1572B. Xor of 3的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 农历七月十五是什么节 有什么讲究
- 下一篇: 无回声结节怎么回事