【NOIP模拟】复制&粘贴

来源:互联网 发布:green网络加速器 官网 编辑:程序博客网 时间:2024/06/05 07:00

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]);    }}
1 0
原创粉丝点击