首页 > 代码库 > NOIP模拟题——复制&粘贴2

NOIP模拟题——复制&粘贴2

【Description】
文本编辑器的一个最重要的机能就是复制&粘贴。JOI社现在正在开发一款能够非常高速地进行复制&粘贴的文本编辑器,作为JOI社一名优秀的程序猿,你担负起了复制&粘贴功能的测试这一核心工作。整个JOI社的命运都系在你的身上,因此你无论如何都想写出一个正确且高速的程序来完成这项工作。
具体的做法如下所示。文件的内容是一个字符串S,对其进行N次复制&粘贴的操作,第i次操作复制位置Ai和位置Bi之间的所有文字,然后在位置Ci粘贴。这里位置x表示字符串的第x个字符的后面那个位置(位置0表示字符串的开头),例如字符串”copypaste”的位置6表示字符’a’和字符’s’之间的位置,位置9表示’e’后面的位置(即字符串的结尾)。不过,如果操作后的字符串长度超过了M,那么将超过的部分删除,只保留长度为M的前缀。
你的任务是写一个程序,输出N次操作后字符串的前K个字符。
【Input】
第一行两个空格分隔的正整数K和M,表示最终输出的文字数量和字符串长度的上限。
第二行一个字符串S,表示初始的字符串。
第三行一个整数N,表示操作的次数。
接下来N行,第i行包含三个空格分隔的整数Ai,Bi,Ci,表示第i次操作将位置Ai到Bi之间的字符串复制,然后粘贴到位置Ci。
【Output】
输出一行一个长度为K的字符串,表示最终的字符串的长度为K的前缀
【Sample Input】
2 18
copypaste
4
3 6 8
1 5 2
4 12 1
17 18 0
【Sample Output】
ac
【HINT】
初始的字符串为”copypaste”。
第一次操作将从位置3到位置6的字符串”ypa”复制,插入位置8,得到字符串”copypastypae”
第二次操作将从位置1到位置5的字符串”opyp”复制,插入位置2,得到字符串”coopyppypastypae”
第三次操作将从位置4到位置12的字符串”yppypast”复制,插入位置1,得到字符串”cyppypastoopyppypastypae”,由于长度超过了M=18,删除超过的部分,得到”cyppypastoopyppypa”
第四次操作将从位置17到位置18的字符串”a”复制,插入位置0,得到字符串”acyppypastoopyppypa”,删除超过18的部分得到”acyppypastoopyppyp”
最后输出长度为2的前缀”ac”即为答案。
【Data Constraint】
对于40%的数据,N,M<=2000
对于100%的数据:
1<=K<=200
1<=M<=10^9
S的每个字符都是小写字母(‘a’~’z’)
K<=|S|<=min(M,2*10^5)
1<=N<=2*10^5
设第i次操作前的字符串长度为Li,那么0<=Ai<Bi<=Li且0<=Ci<=Li (1<=i<=N)

 

 

考试的时候暴力30。。。

正解:由于最后k个一定是没有删除过的,所以倒推找前面一次复制粘贴时的位置。若该点在插入位置的前,则说明位置相对于上一次

复制粘贴没有改变。若该点在插入的末位置后面,则说明位置相当于上一次多了一个x到y的长度,则减去即可。若该点就是删改位置的

其中一个,则它要还原成原来复制的位置,即为它到起点的区间长度加上复制的起点x。

 1 #include<cstdio> 2 #include<iostream> 3 #include<cmath> 4 using namespace std; 5 const int maxn=200005; 6 int k,m,n,ans[maxn]; 7 int a[maxn],b[maxn],c[maxn];char q[maxn]; 8 int main() 9 {10     freopen("A.in","r",stdin);11     freopen("A.out","w",stdout);12     scanf("%d%d",&k,&m);13     scanf("%s",q+1);14     scanf("%d",&n);15     for(int i=1;i<=n;i++)16     scanf("%d%d%d",&a[i],&b[i],&c[i]);17     for(int i=1;i<=k;i++)ans[i]=i;18     for(int i=n;i>=1;i--)//询问19     for(int j=1;j<=k;j++)//有效点20     {21         if(ans[j]<=c[i])continue;//不移动22         if(ans[j]<=c[i]+b[i]-a[i])//属于移动的23         ans[j]=ans[j]-c[i]+a[i];24         else ans[j]-=b[i]-a[i];//加在后面,剪掉长度 25     }26     for(int i=1;i<=k;i++)27     printf("%c",q[ans[i]]);28     return 0; 29 }

 

NOIP模拟题——复制&粘贴2