您的位置:首页 > 其它

【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]);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: