Codeforces936C. Lock Puzzle
生活随笔
收集整理的這篇文章主要介紹了
Codeforces936C. Lock Puzzle
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
給個(gè)串,只能用操作shift x表示把后面x個(gè)字符翻轉(zhuǎn)后放到串的前面。問(wèn)s串怎么操作能變t串。n<=2000,操作次數(shù)<=6100。
打VP時(shí)這轉(zhuǎn)來(lái)轉(zhuǎn)去的有點(diǎn)暈。。。
可以想一種逐步構(gòu)造的方法,即從一個(gè)小的完成構(gòu)造的部分通過(guò)一頓操作,在不影響這部分的前提下擴(kuò)展。
好吧我看題解了,直接丟圖,是從abc擴(kuò)展成xabcy的方法,如果反了就把他最后再倒過(guò)來(lái)。
操作次數(shù)是$\frac{5}{2}n$的,復(fù)雜度$kn$,$k$指操作次數(shù)。
1 //#include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 //#include<map> 6 #include<math.h> 7 //#include<time.h> 8 //#include<complex> 9 #include<algorithm> 10 using namespace std; 11 12 int n; 13 #define maxn 10011 14 char s[maxn],t[maxn];int cnts[30],cntt[30],ans[maxn],lans=0; 15 16 char tmp[maxn]; 17 void shift(int x) 18 { 19 if (x==0) {lans--; return;} 20 memcpy(tmp,s,sizeof(char)*(n+3)); 21 int cnt=0; x=n-x+1; 22 for (int i=n;i>=x;i--) s[++cnt]=tmp[i]; 23 for (int i=1;i<x;i++) s[++cnt]=tmp[i]; 24 } 25 26 int findpos(int p,int rr) 27 { 28 for (int i=rr;i;i--) 29 if (s[i]==t[p]) return i; 30 return maxn*2; 31 } 32 33 int main() 34 { 35 scanf("%d",&n); 36 scanf("%s",s+1); scanf("%s",t+1); 37 for (int i=1;i<=n;i++) cnts[s[i]-'a']++,cntt[t[i]-'a']++; 38 for (int i=0;i<26;i++) if (cnts[i]!=cntt[i]) {puts("-1"); return 0;} 39 40 int p1=(1+n)>>1,p2=p1; 41 int p=findpos(p1,n); p1--; p2++; 42 if (p!=n) {ans[++lans]=n-p; shift(n-p);} 43 bool rev=0; 44 for (int now=1,p;p1;p1--,p2++,now+=2,rev^=1) 45 { 46 if (rev==0) p=findpos(p1,n-now); else p=findpos(p2,n-now); 47 shift(ans[++lans]=n-p); 48 shift(ans[++lans]=n); 49 shift(ans[++lans]=now); 50 if (rev==0) p=findpos(p2,n); else p=findpos(p1,n); 51 shift(ans[++lans]=n-p+1); 52 shift(ans[++lans]=p-now-2); 53 } 54 if (n&1) {if (rev) shift(ans[++lans]=n);} 55 else 56 { 57 if (rev) shift(ans[++lans]=n-1); 58 else 59 { 60 shift(ans[++lans]=n-1); 61 shift(ans[++lans]=1); 62 shift(ans[++lans]=n); 63 } 64 } 65 66 printf("%d\n",lans); 67 for (int i=1;i<=lans;i++) printf("%d ",ans[i]); 68 return 0; 69 } View Code還有一種好理解的逐個(gè)字符構(gòu)造,也是從后往前。
比如說(shuō)現(xiàn)在串是AzB,A的前綴已經(jīng)是t的一個(gè)后綴,z是想加在A前面的字符,B是剩下的。然后這樣:AzB->B'zA'->AB'z->zAB'。搞定。操作次數(shù)3*n。
(好吧這是評(píng)論寫(xiě)的)
轉(zhuǎn)載于:https://www.cnblogs.com/Blue233333/p/8477002.html
總結(jié)
以上是生活随笔為你收集整理的Codeforces936C. Lock Puzzle的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: GB28181协议介绍
- 下一篇: 计算的未来