试题描述 | 为了提高文章质量,每一篇文章(假设全部都是英文)都会有m名编辑审核,每个编辑独立工作,会把觉得有问题的句子通过下标记录下来,比如[1,10],1表示病句的第一个字符,10表示病句的最后一个字符。也就是从1到10个字符组成的句子,是有问题的。 现在需要把多名编辑有问题的句子合并起来,送给总编辑进行最终的审核。比如编辑a指出的病句是[1,10],[32,45];b编辑指出的病句是[5,16],[78,94],那么[1,10]和[5,16]是有交叉的,可以合并成[1,16],[32,45],[78,94]。 | 输入 | 编辑数量m,之后每行是每个编辑的标记的下标集合,第一个和最后一个下标用英文逗号分隔,每组下标之间用分号分隔。 | 输出 | 合并后的下标集合,第一个和最后一个下标用英文逗号分隔,每组下标之间用分号分隔。返回结果是从小到大的递增排列。 | 输入示例 | 3 1,10;32,45 78,94;5,16 80,100;200,220;16,32 | 输出示例 | 1,45;78,100;200,220 | 其他说明 | 对于100%的数据,1<=M<=1e3,句子下标不超过int范围,每个编辑记录的下标不超过1000组。 |
|
思路: 用结构体排序+一个简单贪心即可。按左区间从小到大排序。如果当前的右区间>下一个的左区间,把下一个的左区间置为当前的左区间,把下一个的右区间置为当前与下一个的右区间的最大值。详见代码。 #include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
int m,j,num;
struct sentence
{
int x;//左区间
int y;//右区间
bool operator<(const sentence&sentence2)const//重载小于运算符
{
return x<sentence2.x;//按x(左区间)从小到大排序;
}
}q[1000001];
int main()
{
//freopen("sentence.in","r",stdin);
//freopen("sentence.out","w",stdout);
cin>>m;
for(int i=1;i<=m;i++)
{
while(scanf("%d,%d",&q[j].x,&q[j].y))//这次的输入普遍比较恶心 只要把可爱的cin改成
//scanf100分就到手了mmp
{
num++;//num为结构体个数
j++;
if(getchar()!=';') break;
}
}
sort(q,q+num);//sort
q[num].x=0x7ffffff;//为了防止最后一次判断进入if语句 把第num个不存在的结构体左区间置为无限大
for(int j=0;j<num;j++)
{
if(q[j].y>=q[j+1].x)//如果当前右区间大于下一个的左区间 有重合部分
{
q[j+1].x=q[j].x;//下一个的左区间置为当前的左区间
q[j+1].y=max(q[j+1].y,q[j].y);//下一个的右区间取当前和下一个右区间的最大值(避免
//重叠的情况)
}
else //不满足条件直接输出
{
if(j==num-1) printf("%d,%d",q[j].x,q[j].y);//处理末尾分号
else printf("%d,%d;",q[j].x,q[j].y);//输出;
}
}
}
//抱歉啦可能打的字太多了发出去格式贼恶心qwq |