日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces936C. Lock Puzzle

發(fā)布時(shí)間:2023/12/9 编程问答 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。