20180816 三部曲×2 No.2 sentence

试题描述

为了提高文章质量,每一篇文章(假设全部都是英文)都会有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

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值