【C++周报】第一期2021-8-1

C++周报】第一期 2021-8-1

这一期我们来看这道题目:https://vijos.org/p/1058

这道题是一道非常好的模拟题。题目如下:

 

描述

我们用文本处理器来处理一个特殊的文本文件,该文本文件共有N行文本,每一行文本仅包含一个自然数,第一行为1、第二行为2,以此类推至N行为自然数N。

假设对该文本文件执行一次“剪切和粘贴”操作含义如下:首先选定连续的若干行文本,“剪切”操作将选定的文本从文件中剪下,而“粘贴”操作将剪切下来的文本插入到文件中的其他地方。

编写一个程序求出在进行了连续若干次“剪切和粘贴”操作后,文本文件中前十行的内容。

格式

输入格式

输入的第一行包含两个用空格隔开的自然数N和K,N表示文件的总行数(10≤N≤100,000),K表示“剪切和粘贴”的总次数(1≤k≤1000)。

下面K行每一行包含一次“剪切和粘贴”操作的执行信息,每行包含三个用空格隔开自然数A,B和C,其中1≤A≤B≤N,0≤C≤N-(B-A+1)。A和B表示选定文本的第一行和最后一行,C表示被剪切下来的文本待插入处的前一行,如果C等于0则被剪切下来的的文本将被插入到文件的开头。

输出格式

输出将由十行组成,其中包含所有的操作都完成后的文本文件中前十行所包含的数字。

 

 

我们来分析题意。整个剪切粘贴的过程可以分为如下几步:

第一步,把文本放进缓存区

第二步,把已经剪切掉的部分后面的东西前移上去。

第三步,把要粘贴的地方所有后面的文本后移,腾出位子留给要粘贴的文本。

第四步,把缓存区上的文本粘贴进去。

 

那么,如何进行文本的复制操作呢?如果手动使用for循环,比较麻烦,并且需要注意是从前往后还是从后往前。(把前面的东西复制到后面去,避免数据覆盖,需要从后往前复制,而把后面的复制到前面的反之)

因此,我们可以使用一个函数,memmove!它会自动判断内存重叠的位置,并且自动判断从前往后还是从后往前。我们使用memmove,不仅可以少写几行代码(这个才是主要目的),并且正确性完全得到保证。

 

我们开始正式写代码。为了计算方便,我们可以定义临时变量len存放从ab的长度。

 

#include<bits/stdc++.h>  
using namespace std;  
const int maxn=100010;  
int text[maxn],temp[maxn];  
int n,k,a,b,c;  
int main(){  
  cin>>n>>k;  
  for(int i=1;i<=n;i++)text[i]=i;  
  for(int i=0;i<k;i++){  
    cin>>a>>b>>c;  
    int len=b-a+1;  
    memmove(temp,text+a,sizeof(int)*len);//待粘贴数字  
    memmove(text+a,text+b+1,sizeof(int)*(n-b));//把数字剪切掉  
    memmove(text+c+len+1,text+c+1,sizeof(int)*(n-len-c));//粘贴位置数字后移  
    memmove(text+c+1,temp,sizeof(int)*len);//粘贴进去  
  }  
  for(int i=1;i<=10;i++)cout<<text[i]<<endl;  
  return 0;  
}  

 

 

完成!

posted @ 2021-08-01 20:24  计算机知识杂谈  阅读(106)  评论(0编辑  收藏  举报