C - Flippy Sequence ZOJ - 4060 -列舉4種情況
阿新 • • 發佈:2018-11-10
-
C - Flippy Sequence
- ZOJ - 4060
- 題意:給定兩個0,1串,有兩次操作機會,第一次操作第一個串,第二次操作第二個串。
- 選定一個連續區間把這裡面的數字翻轉,問有多少種方案使得兩串相同。
- 思路:只要分4種情況即可,1,最初全都相同,那麼兩次操作必須選擇相同位置進行操作才符合要求
- 則總情況為(n+1)*n/2 ,也就是長度為n的字串的連續的子串個數
- 2.有一段連續區間不同的,這時兩次操作可以把這一段區間讓這兩次操作分配一下,但是一定要保證
- 它們兩個不重疊且恰好覆蓋這段不同的區間,一種分配情況為1——>到區間長度-1因為不能交叉,
- 它們只能選擇分配不同的區間那麼情況數就是 :區間長度-1,還可以它們其中一個全部選擇這些不同的
- 搭配上原來相同的的字元,每一次這種搭配只能是向(不同區間)的一側,情況又是兩端相同字元長度
- 然後這些情況它們倆都可以交換操作所以情況數*2得出:
-
ans=2*(兩側相同的個數:(x1+n-1-y2)+不同區間的長度:(y2-x1));
- 3.有兩段連續區間不同,那麼他們可以有三種選擇,然後兩個人不同加倍則為6種選擇
- 4.大於兩段連續不同的區間,這樣他們沒有可選擇的餘地了。
-
#include<bits/stdc++.h> using namespace std; #define maxn 1000520 int ans,x1,x2,t,i,j,y2,n; char str[maxn],son[maxn]; int main() { scanf("%d",&t); while(t--) { bool flag=0; x1=x2=-1; scanf("%d%s%s",&n,str,son); for(i=0; i<n; i++) if(str[i]!=son[i]) { x1=i; break; } for(; i<n; i++) if(str[i]==son[i]) { y2=i-1; break; } for(; i<n; i++) if(str[i]!=son[i]) { x2=i; break; } for(; i<n; i++) if(str[i]==son[i]) break; for(; i<n; i++) if(str[i]!=son[i]) { flag=1; break; } if(flag) { printf("0\n"); continue; } if(x2!=-1) { printf("6\n"); continue; } if(x1!=-1) { ans=2*((x1+n-1-y2)+(y2-x1)); printf("%d\n",ans); continue; } ans=n*(n+1)/2; printf("%d\n",ans); } return 0; }