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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Codeforces936C. Lock Puzzle

發布時間:2023/12/9 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Codeforces936C. Lock Puzzle 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

給個串,只能用操作shift x表示把后面x個字符翻轉后放到串的前面。問s串怎么操作能變t串。n<=2000,操作次數<=6100。

打VP時這轉來轉去的有點暈。。。

可以想一種逐步構造的方法,即從一個小的完成構造的部分通過一頓操作,在不影響這部分的前提下擴展。

好吧我看題解了,直接丟圖,是從abc擴展成xabcy的方法,如果反了就把他最后再倒過來。

操作次數是$\frac{5}{2}n$的,復雜度$kn$,$k$指操作次數。

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

還有一種好理解的逐個字符構造,也是從后往前。

比如說現在串是AzB,A的前綴已經是t的一個后綴,z是想加在A前面的字符,B是剩下的。然后這樣:AzB->B'zA'->AB'z->zAB'。搞定。操作次數3*n。

(好吧這是評論寫的)

轉載于:https://www.cnblogs.com/Blue233333/p/8477002.html

總結

以上是生活随笔為你收集整理的Codeforces936C. Lock Puzzle的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。