本题看了别人的做法,顺便熟悉了下multiset。
每个等级对应有一个时间,且等级间可以重复,正好用multiset。注意set插入元素后自动排序,以及set的末尾元素是1073741823(无穷大),而multiset又可以看成是一个二维数组,所以可以通过it == S[j].end()来判断该元素是否为空。还要注意定义迭代器类型后,调用时相当于是对指针的调用。
此外,还学到cmp函数也可写在结构体内部,相当于运算符重载。
#include <stdio.h>
#include <cstdio>
#include <set>
#include <string>
#include <algorithm>
using namespace std;
const int N = 100005;
struct TASK
{
int x, y;
bool operator < (const TASK &n1) const
{
if(x != n1.x) return x > n1.x;
return y > n1.y;
}
}task[N];
int main()
{
// freopen("in.txt", "r", stdin);
int n, m, i, j, x0, y0, x, y, num;
__int64 sum;
while(~scanf("%d%d", &n, &m))
{
multiset <int> S[105];
for(i = 0; i < n; i ++)
{
scanf("%d%d", &x0, &y0);
S[y0].insert(x0);
}
for(i = 0; i < m; i ++)
scanf("%d%d", &task[i].x, &task[i].y);
num = sum = 0;
sort(task, task + m);
for(i = 0; i < m; i ++)
{
x = task[i].x;
y = task[i].y;
for(j = y; j <= 100; j ++)
{
if(S[j].empty()) continue;
multiset <int> :: iterator it = S[j].lower_bound(x);
if(it == S[j].end() || *it < x) continue;
else
{
num ++;
sum += (500 * x + 2 * y);
S[j].erase(it);
break;
}
}
}
printf("%d %I64d\n", num, sum);
}
return 0;
}