您的位置:首页 > 理论基础 > 数据结构算法

17.7.7 NOIP模拟赛 【模拟/数据结构】【模拟】

2017-07-07 15:47 281 查看
1.hao







【题解】

这道题我们要搞清楚几个问题:

1.连续三个同色的如果没有被碰到是不会被消除的;

2.输入数据里边可能有空串(不是“-”,而是直接是空的一行),也可能有连着;

3.string.h中函数的作用;

然后来谈谈做法:这道题要我们模拟出插入,删除的操作。也就是说我们需要将字符串向右平移一位,插入,向左平移三位或多位。对于需要移动数组的操作,我们用strcpy函数来解决。

下面我们看看代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#define NAME "hao"
using namespace std;
const int N=20000;
char ch[N+5],temp[N+5];
int size,pos;
int n;
char e;
bool check(int a)
{
int head=a,last=a;
char elem;
elem=ch[a];
while(ch[head]==elem&&head)head--;
if(head||ch[head]!=elem)head++;
while(ch[last]==elem&&last<size)last++;//找到需要删除的部分
if(last-head>=3)//连成三个及其以上
{
strcpy(temp,ch+last);
strcpy(ch+head,temp);
size=size+head-last;
pos=head;//更改pos,下一次(如果必要的话)可以在此继续删除
return true;
}
else return false;
}
int main()
{
freopen(NAME".in","r",stdin);
freopen(NAME".out","w",stdout);
gets(ch);//解决输入空串的问题
while(ch[size]>='A'&&ch[size]<='Z')size++;
scanf("%d",&n);
while(n--)
{
scanf("%d %c",&pos,&e);
strcpy(temp,ch+pos);
strcpy(ch+pos+1,temp);
ch[pos]=e;size++;
while(check(pos)&&size);//放在while里边反复运行,直到删干净
if(size)printf("%s\n",ch);
else printf("-\n");
}
return 0;
}


2.kun



【题解】

由题意可知,不论是找最大字典序,还是去输出从到大小的排序,都有一个共同点,那就是最大的一定最先出来,较大的尽量先出来。所以我们是否放这个元素进栈的判定就是看这个元素过后是否有比他大的。为此,我们就需要存储不同区间的最大值。刚开始我想用一个线段树来查询区间最值,后来才知道,一个数组就可以解决。

我们来看代码:

#include<stack>
#include<cstdio>
#include<iostream>
#define NAME "kun"
const int N=1000000;
using namespace std;
stack<int> s;
int n;
int m[N+5],a[N+5];//m[i]表示[i,n]内的最大值
int main()
{
freopen(NAME".in","r",stdin);
freopen(NAME".out","w",stdout);
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
for(int i=n;i>=1;i--)
m[i]=max(a[i],m[i+1]);
s.push(a[1]);
for(int i=2;i<=n;i++)
{
while((!s.empty())&&(s.top()>m[i]))
printf("%d ",s.top()),s.pop();//让大的先出来
s.push(a[i]);
}
while(!s.empty())
printf("%d ",s.top()),s.pop();
return 0;
}


以上

2017.7.7
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: