第八次模拟测试=2

题目描述:
众所周知,ZJM 住在 B 站。

这一天 Q 老师来找 ZJM 玩,ZJM 决定向 Q 老师展现一下自己快速看番的本领。

ZJM 让 Q 老师任意挑选了一部番,Q老师一眼看中了《辉夜大小姐想让我告白》,已知这部番一共有 N 个精彩片段,每个精彩片段用 [L[i], R[i]] 来表示。

ZJM 从第一分钟开始看,每次可以按下快进键,快进 X 分钟,问 ZJM 最快需要多久可以看完这部番。

Input
第一行给出两个整数 N、X(1 ≤ N ≤ 50, 1 ≤ X ≤ 1e5)

接下来 N 行,每行给出两个整数,L[i]、R[i](1 ≤ L[i] ≤ R[i] ≤ 1e5)

数据保证,R[i-1] < L[i]

Output
输出一个整数,表示 ZJM 最快看完这部番的时间。

Examples
Input
2 3
5 6
10 12
Output
6
Input
1 1
1 100000
Output
100000
Note
在第一个样例中,ZJM 从第 1 分钟开始看,由于 [1, 3] 区间内没有精彩片段,因此 ZJM 快进到了第 4 分钟。

观看完 [4, 6] 区间的内容后,时间来到了第 7 分钟,由于 [7, 9] 区间内没有精彩片段,因此 ZJM 快进到了第 10 分钟,观看完 [10, 12] 区间的内容后,看番结束。

一共耗时 3 + 3 = 6 分钟。
题目分析:
这是一个贪心问题,首先我们要找出有可能进行快进的区间,可以用一个布尔数组表示,在精彩区间内都设置为1表示不能快进,其余的0就表示可以快进,当然这里已经表明精彩内容是有序的,所以不用排序,不过不排序也无妨,本题对精彩内容的出现顺序无关。

	for(int i=1;i<=n;i++)
	{
		cin>>t[i].l>>t[i].r;
		for(int j=t[i].l;j<=t[i].r;j++)
		{
			view[j]=true;
		}
	}

然后就是看能不能快进的问题了,我一开始做题的时候想错了,是按照x长度的区间从前往后每x个长度进行扫描,后来发现并不是这样的,比如如果每次快进5分钟,第一次精彩时间是1-3分钟,按照我一开始的算法是扫描1-5,6-10…这些区间,实际上不是的,直接从第4分钟就可以扫描了。那这样我们就需要记录下非精彩时间的区间长度,当然区间不止一个,所以我们需要记录下各个区间的长度,这里要注意移动到下一个区间计数的条件是前一个结点在精彩时间,下一个结点就不在精彩区间了,也就是说连续的精彩区间我们是不管的。

	for(int i=1;i<=t[n].r;i++)
	{
		if(view[i]==false)
		{
			a[count]++;
		}
		else if(view[i]==true&&view[i+1]==false)
		{
			count++;
		}
	}

然后就可以用总的时间减去快进的时间了,这样在能快进区间内的时间能快进就快进,如果时长小于快进时间的话就不快进。

	int total=t[n].r;
	for(int i=1;i<count;i++)
	{
		if(a[i]>=x)
		{
			total=total-x*(a[i]/x);
		}
	}
	cout<<total;

代码如下:

#include<iostream>
using namespace std;
struct time
{
	int l;
	int r;
}t[100010];
bool view[100010]={0};
int a[100010]={0};
int main()
{
	int n,x;
	cin>>n>>x;
	for(int i=1;i<=n;i++)
	{
		cin>>t[i].l>>t[i].r;
		for(int j=t[i].l;j<=t[i].r;j++)
		{
			view[j]=true;
		}
	}
	int count=1;
	for(int i=1;i<=t[n].r;i++)
	{
		if(view[i]==false)
		{
			a[count]++;
		}
		else if(view[i]==true&&view[i+1]==false)
		{
			count++;
		}
	}
	int total=t[n].r;
	for(int i=1;i<count;i++)
	{
		if(a[i]>=x)
		{
			total=total-x*(a[i]/x);
		}
	}
	cout<<total;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值