题目:http://codeforces.com/contest/936/problem/C

  玩了一个小时,只能想出 5*n 的方法。

  经过一番观察?考虑这样构造:已经使得 A 串的一个后缀 = B 串的一个前缀,考虑再把一个正确的字符挪到 A 串的最后面。

  设该字符为 x 、它之前有 len 个字符、当前已经弄好的结尾长度为 l2 。

  进行这5个操作:n-len , len , n-len-l2 , l2 , n-l2+1 。

  思路就是:

  1&2:使得 x 变成结尾;

  3:使 x 变成开头、原来做好的部分变成结尾;

  4:原来做好的部分拼到 x 前面;

  5:新的做好的部分变成后缀。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int N=,K=;
  6. int n,m,ct[K];
  7. char a[N],b[N];
  8. void Rv(int l,int r)
  9. {
  10. for(int i=l,j=r;i<j;i++,j--)
  11. swap(a[i],a[j]);
  12. }
  13. void To_tail(int x)
  14. {
  15. char w=a[x];
  16. for(int i=x;i<n;i++)a[i]=a[i+];
  17. a[n]=w;
  18. }
  19. int main()
  20. {
  21. scanf("%d%d",&n,&m);
  22. scanf("%s",a+); scanf("%s",b+);
  23. for(int i=;i<=n;i++)
  24. ct[a[i]-'a']++;
  25. for(int i=;i<=n;i++)
  26. ct[b[i]-'a']--;
  27. for(int i=;i<K;i++)
  28. if(ct[i]!=){puts("-1");return ;}
  29. if(m<*(n-)+){puts("-1");return ;}
  30. printf("%d\n",*(n-)+*(b[]!=a[n]));//not +2!!!
  31. int len=;
  32. if(b[]!=a[n])
  33. {
  34. for(int i=;i<=n;i++)
  35. if(a[i]==b[]){len=i-;break;}
  36. printf("%d %d ",n-len,len);
  37. Rv(,len); Rv(len+,n);
  38. }
  39. for(int l2=,ps=;l2<n;l2++,ps++)
  40. {
  41. for(int i=;i<=n;i++)
  42. if(a[i]==b[ps]){len=i-;break;}
  43. printf("%d %d %d %d %d ",n-len,len,
  44. n-len-l2,l2,n-l2-);
  45. Rv(len+,n-l2); To_tail(n-l2);
  46. }
  47. puts(""); return ;
  48. }

  刚才写着题解,忽然发现可以随随便便变成 3*n 的嘛!

  1.n-len-1,使得 x 变成结尾,并且原来做好的部分倒序变成开头;

  2.1,使 x 接在最前面;

  3.n,整体翻转,就变成正序的“原来做好的部分”后面添了一个 x 了!

  题解是 2.5*n 的。考虑做好的部分允许在过程中变成倒序的,然后一次5个操作往上添2个字符。

  设现在 A 串的后缀是 B 串的 [ L , R ] 部分。考虑扩充成 [ L-1 , R+1 ] 。设 y 是要往 A 的最后面放的、 x 是要往“已经做好的部分”的前面放的。

  1.把 x 露出来(放到结尾),此时原来做好的部分倒序在开头;

  2.翻转整个序列,现在原来部分正序在结尾, x 在开头;

    这一步很巧妙!这样可以让再做一步之后,原来部分的另一端露在开头;

  3.原来部分接在最前面;此时原来部分是倒序;

  4.找到 y 的位置,操作含 y 的对应后缀,这样 y 接在了“倒序的原来部分”的前面,并且整个部分在序列里面;

    这一步的思想很大胆!允许做好的部分埋在序列中部;

  5.操作后缀,使得做好的部分成为后缀;此时的做好部分是翻转过的状态,即原来按顺序对应的是 [ L , R ] 的话,现在是 [ R , L ] 。

  1. #include<cstdio>
  2. #include<cstring>
  3. #include<algorithm>
  4. using namespace std;
  5. const int N=,M=,K=;
  6. int n,m,ct[K],p[M],tot;
  7. char a[N],b[N],c[N];
  8. void cz(int x)
  9. {
  10. for(int i=n-x+,j=x;i<=n;i++,j--)
  11. c[j]=a[i];
  12. for(int j=x+,i=;j<=n;i++,j++)
  13. c[j]=a[i];
  14. memcpy(a,c,sizeof c); p[++tot]=x;
  15. }
  16. int main()
  17. {
  18. scanf("%d%d",&n,&m);
  19. scanf("%s",a+); scanf("%s",b+);
  20. for(int i=;i<=n;i++)
  21. ct[a[i]-'a']++;
  22. for(int i=;i<=n;i++)
  23. ct[b[i]-'a']--;
  24. for(int i=;i<K;i++)
  25. if(ct[i]!=){puts("-1");return ;}
  26. int l,r,x,y; l=r=(n+)>>;
  27. if(a[n]!=b[l])
  28. {
  29. for(int i=;i<=n;i++)
  30. if(a[i]==b[l]){x=i;break;}
  31. cz(n-x);
  32. }
  33. bool fx=;
  34. for(l--,r++;l>=;l--,r++)
  35. {
  36. for(int i=;i<=n;i++)
  37. if(a[i]==b[l]){x=i;break;}
  38. for(int i=;i<=n;i++)
  39. if(a[i]==b[r]&&i!=x){y=i;break;}
  40. if(fx)swap(x,y); fx=!fx; char tp=a[y];
  41. cz(n-x); cz(n); cz(r-l-);
  42. for(int i=r-l+;i<=n;i++)
  43. if(a[i]==tp){y=i;break;}
  44. int tmp=n-y; cz(n-y+); cz(n-tmp-(r-l+));
  45. }
  46. if((n&)==&&!fx){ cz(n-); cz(); fx=!fx;}
  47. if(fx)cz(n);
  48. printf("%d\n",tot);
  49. for(int i=;i<=tot;i++)printf("%d ",p[i]);puts("");
  50. return ;
  51. }

CF 936C Lock Puzzle——构造的更多相关文章

  1. CF936C Lock Puzzle 构造

    传送门 好久不做构造题脑子都僵化了qwq 无解的条件是\(s\)包含的字符可重集和\(t\)包含的字符可重集不相等,相等的时候下文会给出一种一定可行的构造方案. 考虑增量构造.定义某个字符串\(x\) ...

  2. hduoj 4708 Rotation Lock Puzzle 2013 ACM/ICPC Asia Regional Online —— Warmup

    http://acm.hdu.edu.cn/showproblem.php?pid=4708 Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/O ...

  3. HDU 4708:Rotation Lock Puzzle

    Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  4. hdu4708 Rotation Lock Puzzle

    Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others ...

  5. Codeforces Round #467 (Div. 2) E -Lock Puzzle

    Lock Puzzle 题目大意:给你两个字符串一个s,一个t,长度<=2000,要求你进行小于等于6100次的shift操作,将s变成t, shift(x)表示将字符串的最后x个字符翻转后放到 ...

  6. HDU 4708 Rotation Lock Puzzle (简单题)

    Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  7. HDUOJ---(4708)Rotation Lock Puzzle

    Rotation Lock Puzzle Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Oth ...

  8. Lock Puzzle CodeForces - 936C (构造)

    大意: 给定字符串$s$,$t$, 每次操作可以将$S=AB$变为$S=B^RA$, 要求$3n$次操作内将$s$变为$t$. #include <iostream> #include & ...

  9. Rotation Lock Puzzle

    Problem Description Alice was felling into a cave. She found a strange door with a number square mat ...

随机推荐

  1. ADFS 2016 & Dynamics CRM

    参考:https://blog.csdn.net/vic0228/article/details/80188291 webapp 获取token https://adfs.demo.local/adf ...

  2. jmeter两种录制方式

    jmeter两种录制方式 一.Badboy Badboy是一款不错web自动化测试工具,利用它来录制脚本,并且录制的脚本可以直接保存为JMeter文件来使用. Badboy  version 2.1. ...

  3. shtml与html

    前言 在浏览网页的时,忽然发现了一个网址不是以[.html]结尾,而是[.shtml].顿时勾起了我的好奇心,这是什么鬼?于是打开google,开始维基. SHTML 什么是 SHTML 使用SSI( ...

  4. No-sql之redis常用命令

    转自:http://blog.csdn.net/nicewuranran/article/details/51793760 No-SQL之Redis 介绍 Redis是一种基于内存存储的key-val ...

  5. Cookie/Session/Local Storage/IndexedDB

    本文主要总结客户端/浏览器端数据存储的技术. 在客户端或者浏览器端存储,可以快速的访问页面,当前主要有Cookie,Session,Local Storage,IndexedDB四种(WebSQL呗废 ...

  6. Spring Cloud Stream 进行服务之间的通讯

    Spring Cloud Stream Srping cloud Bus的底层实现就是Spring Cloud Stream,Spring Cloud Stream的目的是用于构建基于消息驱动(或事件 ...

  7. [Bzoj2243][SDOI2011]染色(线段树&&树剖||LCT)

    题目链接:https://www.lydsy.com/JudgeOnline/problem.php?id=2243 线段树+树链剖分,在线段树需要每次用lt和rt两个数组记录当前区间的左右边界的颜色 ...

  8. dp(最长公共子序列)

    A subsequence of a given sequence is the given sequence with some elements (possible none) left out. ...

  9. 【题解】Hankson 的趣味题

    题目大意 已知正整数$a_{0}$.$a_{1}$.$b_{0}$.$b_{1}$($1 \leq a_{0}, a_{1}, b_{0}, b_{1} \leq 2 \times 10^{9}$), ...

  10. Centos7.6替换自带的jre安装jdk

    Centos7.6自带jre 1.8,可以作为java运行环境.但如果要编译java程序那就需要jdk,以下介绍如何把自带的jre卸掉并安装jdk 首先要卸载自带的jre PS:由于不同版本的操作系统 ...