zl程序教程

您现在的位置是:首页 >  其它

当前栏目

容易的网络游戏(normal)

容易 normal
2023-09-27 14:28:30 时间

容 易 的 网 络 游 戏 ( n o r m a l ) 容易的网络游戏(normal) (normal)

题目链接:SSL 1231

题目

现在网络游戏一款接一款地推出,佳佳和他的同学们也迷上了网络游戏。他们最近在玩 N N N款不同的网络游戏。
  一些网络游戏允许玩家购买双倍经验卡。拥有双倍经验卡的玩家可以在有效期内获得更多的经验值。佳佳和他的同学们有着丰富的网游经验,对于任何一款网络游戏,只要是在双倍经验的条件下,无论谁玩都可以在单位时间内轻松获得一个单位的经验值。
  国庆节马上到了,网游公司不会错过这难得的机会大捞一把。中国网游常用的赚钱手段便是免费提供双倍经验(因为如果玩家再买一张双倍卡,便可获得 4 4 4倍经验)。
  在 9 9 9 10 10 10 11 11 11月份,佳佳和他的同学们玩的 N N N个网络游戏中每一个都会有一段开放免费双倍经验的时间。佳佳事先作了调查,他已经把每一款网游的双倍经验开放时间都记了下来。佳佳是不会乱用自己的零花钱购买双倍经验卡的,他决定在免费双倍经验时叫同学到家里一起玩;同时,他们也不会浪费自己的时间,为了提高效率,他们只玩处于免费双倍经验开放时期的游戏。
  我们假定,每台电脑最多只能有一人操作,一个人最多只能操作一台电脑;并且每款游戏最多只能在一台电脑上玩,每台电脑最多运行一个游戏。我们忽略开始游戏和结束游戏时所消耗的时间。
  现在佳佳想知道,假如佳佳共有 M M M台电脑,且佳佳一共叫来了 P P P个同学,那么他和他的同学们最多能得到多少单位的经验呢?

输入

第一行有三个用空格隔开的整数 N N N, M M M P P P,它们表示的意义如题目描述。
以下 N N N行,每行有两个用空格隔开的整数 X i Xi Xi, Y i Yi Yi,表示从 X i Xi Xi单位时间到 Y i Yi Yi单位时间为第i款游戏开放双倍经验的时间。

输出

一个整数,表示佳佳和他的同学们能获得的最大经验值。

样例输入

1 1 1
0 100

样例输出

101

数据范围

对于 70 % 70\% 70%数据, 0 &lt; = X i , Y i &lt; = 10000 0&lt;=X_i,Y_i&lt;=10000 0<=Xi,Yi<=10000
对于 100 % 100\% 100%数据, 0 &lt; = X i , Y i &lt; = 5000000 0&lt;=X_i,Y_i&lt;=5000000 0<=Xi,Yi<=5000000 X i &lt; = Y i X_i&lt;=Y_i Xi<=Yi 0 &lt; = P &lt; = 2147483647 0&lt;=P&lt;=2147483647 0<=P<=2147483647 1 &lt; = N &lt; = 1000 1&lt;=N&lt;=1000 1<=N<=1000 1 &lt; = M &lt; = 1000 1&lt;=M&lt;=1000 1<=M<=1000

思路

这道题我们用离散化来做。
在读入的时候,因为经验为结束时间 − - 开始时间 + 1 +1 +1,我们不妨把开始时间减一,这样经验就为结束时间 − - 开始时间。
而且因为 p p p只是他叫来的人数,如果要知道能玩游戏的人数,还要加上他自己 ( + 1 ) (+1) +1
然后我们就看一下最多能获得多少经验,就可以了。

代码

#include<cstdio>
#include<algorithm>
#define min(x, y) (x) < (y) ? (x) : (y)
#define ll long long

using namespace std;

ll n, m, p, a[3][1001], b[2001], k, ans;

int main() {
	scanf("%lld %lld %lld", &n, &m, &p);//读入
	p++;//加上他自己
	for (ll i = 1; i <= n; i++) {
		scanf("%lld %lld", &a[1][i], &a[2][i]);//读入
		a[1][i]--;//处理一下
		b[++k] = a[1][i];//记录
		b[++k] = a[2][i];//记录
	}
	
	sort(b + 1, b + k + 1);//离散化
	
	for (ll i = 1; i < k; i++) {
		ll lc = min(m, p);//最多可以选多少个游戏
		for (ll j = 1; j <= n; j++) {//枚举每一个游戏
			if (b[i] >= a[1][j] && b[i + 1] <= a[2][j]) {//此区间有游戏玩
				lc--;//选的游戏量减一
				ans += b[i + 1] - b[i];//记录经验
			}
			if (!lc) break;//选不了了
		}
	}
	
	printf("%lld", ans);//输出
	
	return 0;
}