zoukankan      html  css  js  c++  java
  • 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 }
  • 相关阅读:
    k8s运行容器之Job应用(6)
    k8s创建资源的两种方式及DaemonSet应用(5)
    kubernetes架构及deployment应用(4)
    docker部署harbor私有镜像库(3)
    k8s集群部署(2)
    kubernetes介绍(1)
    Docker网络(5)
    Docker存储(4)
    Docker镜像的仓库及底层依赖的核心技术(3)
    Docker的镜像及容器常用操作(2)
  • 原文地址:https://www.cnblogs.com/937337156Zhang/p/6062357.html
Copyright © 2011-2022 走看看