期末考试--nyoj-757

 

期末考试

时间限制:1000 ms  |  内存限制:65535 KB
难度:2
描述
马上就要考试了,小T有许多作业要做,而且每个老师都给出来了作业要交的期限,如果在规定的期限内没
交作业就会扣期末成绩的分数,假设完成每门功课需要一天的时间,你能帮助小T扣除的分数最小吗?
 
输入
输入n,表示n门功课(n<2000),接下来n行,每行两个数a,b,分别表示交作业的最后期限,迟交扣除的分数。
(以文件结尾)
输出
输出扣除的最小分数。
样例输入
3
3 10
3 5
3 1
3
1 6
3 2
1 3
7
1 3
4 2
6 1
4 7
2 6
4 5
3 4
样例输出
0
3
5




这个题我做的时候这是一头雾水,看了网上的代码才知道该怎么写!下面把我的想法给大家说一下!


分析:
你首先要对日期进行排序,要是没有重复的日期就好了,一天一个,这肯定挂不了科啊!。有也没事,先按日期从小到大,有重复日期的,按分值的从小到大排序。
排好后,我们本着一天一个的原则,当遇到重复日期的时候就要有所取舍了,那肯定是不要分值少的啊,所以就和前面最小的比较,看哪个更小,就不复习了分数不要了!
不要的分数加起来就是最小的了!这个题就是要利用优先队列了!因为它能自动排序,省下不少事!


 1 #include<stdio.h>
 2 #include<queue>
 3 #include<algorithm>
 4 using namespace std;
 5 struct as
 6 {
 7     int x;
 8     int y;
 9 }aa[3000];//定义一个存放输入数据的结构体
10 bool cmp(as m,as n)//定义结构体排序的顺序
11 {
12     if(m.x<n.x)
13     return true;
14     else if(m.x==n.x&&m.y<n.y)
15     return true;
16     return false;
17 }
18 int main()
19 {
20     int n;
21     priority_queue<int ,vector<int>,greater<int> >s;//定义一个队列
22     while(scanf("%d",&n)!=EOF)
23     {
24         int i;
25         while(!s.empty())
26         s.pop();//清空队列
27         for(i=0;i<n;i++)
28         scanf("%d %d",&aa[i].x,&aa[i].y);
29         sort(aa,aa+n,cmp);//排序
30         int sum=0;
31         for(i=0;i<n;i++)
32         {
33             if(s.size()<aa[i].x)//这里的是s.size()可以看成已经用的天数,进入队列一个数据就花一天时间
34             s.push(aa[i].y);
35             else
36             {
37                 if(aa[i].y>s.top())比较和队首元素的大小(因为现在队首已经是最小的了),如果当前更小,就舍去当前的这门学科
38                 {
39                     sum+=s.top();
40                     s.pop();
41                     s.push(aa[i].y);
42                     
43                 }
44                 else
45                 sum+=aa[i].y;
46             }
47         }
48         printf("%d
",sum);
49     }
50     return 0;
51  } 
原文地址:https://www.cnblogs.com/Eric-keke/p/4682769.html