【NOIP模拟】复制&粘贴
2016-04-02 16:08
225 查看
Description
文本编辑器的一个最重要的机能就是复制&粘贴。JOI社现在正在开发一款能够非常高速地进行复制&粘贴的文本编辑器,作为JOI社一名优秀的程序猿,你担负起了复制&粘贴功能的测试这一核心工作。整个JOI社的命运都系在你的身上,因此你无论如何都想写出一个正确且高速的程序来完成这项工作。具体的做法如下所示。文件的内容是一个字符串S,对其进行N次复制&粘贴的操作,第i次操作复制位置Ai和位置Bi之间的所有文字,然后在位置Ci粘贴。这里位置x表示字符串的第x个字符的后面那个位置(位置0表示字符串的开头),例如字符串”copypaste”的位置6表示字符’a’和字符’s’之间的位置,位置9表示’e’后面的位置(即字符串的结尾)。不过,如果操作后的字符串长度超过了M,那么将超过的部分删除,只保留长度为M的前缀。
你的任务是写一个程序,输出N次操作后字符串的前K个字符。
Solution
其实这道题非常简单。我一开始看错了数据范围,还以为k有100000那么大,实际上只有200,TAT……
由于最后一个操作后前两百是固定的,但是从哪里来不确定,我们可以倒着做。
首先设x为当前第i位在第j次操作的位置,初始值明显是i。
现在我们要追根溯源。
每次遇到一个范围a到b,因为是从原串复制粘贴的,所以可以分类一下。第一种情况就是粘贴过来覆盖了这个位置,第二种情况就是粘贴到了这个位置的前面,然后转移很显然。
Code
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #define fo(i,a,b) for(i=a;i<=b;i++) #define fod(i,a,b) for(i=a;i>=b;i--) using namespace std; const int maxn=200007; int i,j,k,l,t,n,m,ans; char s[10000000]; int a[maxn],b[maxn],c[maxn]; int main(){ freopen("copypaste.in","r",stdin); freopen("copypaste.out","w",stdout); scanf("%d%d",&k,&m); scanf("%s",s+1); n=strlen(s+1); scanf("%d",&l); fo(i,1,l){ scanf("%d%d%d",&a[i],&b[i],&c[i]); a[i]++;c[i]++; } fo(i,1,k){ t=i; fod(j,l,1){ if(c[j]<=t&&t<=c[j]+b[j]-a[j]){ t=a[j]+(t-c[j]); } else if (c[j]+b[j]-a[j]<t)t-=(b[j]-a[j]+1); } putchar(s[t]); } }
相关文章推荐
- 股票证券交易术语
- php之常量
- ALERT日志中常见监听相关报错之中的一个:ORA-609错误的排查
- 第三章 springboot + jedisCluster
- Android studio开发常用快捷键
- Android drawable利用shape绘制虚线
- java atomic
- js--面向对象--封装
- 《C++ Primer》 第四版 第16章 模板与泛型编程
- AX V2 Series Computers
- WebView实战与设计
- Association Rules and the apriori algorithm
- LVS负载均衡技术介绍
- C/C++读入写出空格和\0的区别
- Tomcat配置https
- jsp中跳转到el表达式中保存的其他网站的url
- 【计算机网络】:TCP协议中的三次握手和四次握手
- 多重背包二进制原理拆分问题
- 观察者模式深入实践
- 内联汇编语法和使用方法