资源限制
时间限制:1.0s 内存限制:256.0MB
问题描述
有一天,盾神捡到了好多好多五颜六色的珠子!他心想这些珠子这么漂亮,可以做成一条项链然后送给他心仪的女生~于是他用其中一些珠子做成了长度为n的项链。当他准备把项链首尾相接的时候,土方进来了。
“哇这么恶心的项链你也做得出来!!!”
盾神自知审美不是他的长项,于是他很谦虚地请教土方,怎么才能把项链做得漂亮。
“这个嘛首先你要在这里加上一个这种颜色的珠子,然后在这里去掉这个珠子,然后……,最后你看看是不是漂亮很多咧”土方一下子说出了m个修改步骤。
盾神觉得这个用人工做太麻烦了,于是交给了你。
输入格式
第一行两个数,分别为n,m。
第二行n个数,表示盾神一开始的项链。第i个数表示第i颗珠子的颜色。
接下来m行,为以下形式之一:
ADD P Q:表示在颜色为P的珠子前面加上一个颜色为Q的珠子。
DEL P:表示把颜色为P的珠子去掉,如果它不在端点处,则需要把它旁边的两颗珠子连起来。例如某时刻项链状态为1 4 5 8,则执行DEL 4会变成1 5 8,执行DEL 1会变成4 5 8。
输入保证在每次操作之前,项链有颜色为P的珠子,且任意时刻珠子颜色互不相同。
输出格式
第一行为一个数len,为做完所有操作后,项链的长度。
第二行len个数,表示此时项链的状态。第i个数表示第i颗珠子的颜色。
样例输入
10 5
1 2 3 4 5 6 7 8 9 10
DEL 5
ADD 7 5
DEL 10
ADD 4 20
ADD 20 12
样例输出
11
1 2 3 12 20 4 6 5 7 8 9
数据规模和约定
表示颜色的数字不超过105的正数,1<=n<=104,1<=m<=10^4。
解题思路:
本题按照题目要求来使用链表进行操作即可,不过使用链表时有个小技巧,就是增加一个附加头结点,因为是用整形数据(int)表示珠子的颜色,所以头结点的int型变量可以表示除头结点外其余链结点的个数,输出时,珠子的个数即为头结点中int型属性的值,加一个附加头结点,也方便了删除和增加珠子的操作,不需要对首节点进行分情况讨论,增加题解的复杂度
#include<iostream>
#include<string.h>
using namespace std;
struct Lian{//链表
int color;//头结点表示个数,其他结点表示颜色
Lian *link;//指向下一个
Lian(){//无参构造函数
color=-1;link=NULL;
}
Lian(int co){//有一个参数的有参构造函数
color=co;link=NULL;
}
};
int n,m;//表示竹子个数和操作次数
Lian *first=new Lian();//定义头结点
void Del(int a);//删除珠子a
void Add(int a,int b);//在珠子a前面加珠子b
int main()
{
cin>>n>>m;
int i;//循环变量
int color;//表示输入的颜色
char str[4];//表示输入的
first->color=0;//表示只有0个珠子
Lian *t=first;//t指向要加入数据的前一个结点
int a,b;//表示输入的数
for(i=0;i<n;i++){
cin>>color;
first->color++;
Lian *Next=new Lian(color);//新建一个珠子
t->link=Next;
t=t->link;
}
for(i=0;i<m;i++){
cin>>str;
if(strcmp(str,"DEL")==0){
cin>>a;//表示要删除的数
Del(a);//删除a
}
else{
cin>>a>>b;//在数a前添加b
Add(a,b);
}
}
cout<<first->color<<endl;
t=first->link;
while(t!=NULL){
cout<<t->color<<" ";
t=t->link;
}
cout<<endl;
return 0;
}
void Del(int a)//删除珠子a
{
first->color--;
Lian *left=first;//指向后面那个
Lian *right=first->link;//指向前面那个
while(right!=NULL){
if(right->color==a){//找到珠子a
left->link=right->link;
break;
}
right=right->link;
left=left->link;
}
delete []right;
}
void Add(int a,int b)//在珠子a前面加珠子b
{
first->color++;
Lian *left=first;//后一个
Lian *right=first->link; //前一个
while(right!=NULL){
if(right->color==a){//在珠子a之前加入珠子b
Lian *temp=new Lian(b);//新建一个结点
temp->link=right;
left->link=temp;
break;
}
left=left->link;
right=right->link;
}
}