NOIP2012提高组day2 T2借教室

这题骗分可以骗到满分(可能是数据不太强给强行过去了)

这道题如果是按照题意去模拟用循环去修改区间的话只有45分,正解是二分+差分数组,骗分也是差分数组但是没有使用二分,时间复杂度在最坏的情况下是O(n*m),数据良心并没有这种最坏的情况。

拿样例举例:

四天里,每一天的教室的可用数量为

2 5 4 3

读入订单,然后利用差分修改区间避免超时,不考虑教室的数量下限,修改后每一天的教室的可用数量为

0 -4 -5 -4

然后从第一天到最后一天遍历,如果当天的教室可用数量小于0,则当天的教室是不够用了的,模拟当天的情况,然后更新答案。

订单1:每天借两间,从第一天到第三天

订单2:每天借三间,从第二天到第四天

订单3:每天借四间,从第二天到第四天

第一天:0,不小于0

第二天:-4,小于0,模拟当天情况,原来的教室可用数量为5,从订单1到订单3模拟,第二天在订单1的区间内,教室的可用数量减去2,目前可用数量为3。 在订单2的区间内,可用数量减去3,目前可用数量变为0。 在订单3的区间内,可用数量减去4,目前可用数量为-4,在订单3时可用数量变为小于0,需要修改订单的订单为订单3,答案更新为3

第三天:-5,小于0,原来可用数量为4,在订单1的区间内,-2,可用数量变为2,在订单2的区间内,-3,可用数量变为-1,小于零,需要修改订单的订单为订单2,订单2的顺序在订单3之前,按照题意,先到先得,答案更新为2

第四天:………………(按照上面继续模拟)

骗分大法神奇qwq

贴上代码

 1 var
 2         n,m,i,j,k,ans:longint;
 3         r,d,s,t,a,b:array[1..1000000] of longint;
 4         flag:boolean;
 5 begin
 6         readln(n,m);
 7         for i:=1 to n do
 8                 read(r[i]);  //读入每天的可用教室数量
 9         for i:=1 to m do
10         begin
11                 readln(d[i],s[i],t[i]);  //读入订单
12                 a[s[i]]:=a[s[i]]-d[i];
13                 a[t[i]+1]:=a[t[i]+1]+d[i];  //差分数组预处理
14         end;
15         k:=0;
16         for i:=1 to n do
17         begin
18                 k:=k+a[i];
19                 b[i]:=r[i]+k;   //差分
20         end;
21         ans:=maxlongint;  //ans初始化
22         flag:=true;  //标记是否满足所有订单
23         for i:=1 to n do  //枚举每天的可用教室
24                 if b[i]<0 then  //如果可用教室数量小于0
25                 begin
26                         flag:=false;  //不可能满足所有订单
27                         for j:=1 to m do
28                                 if (i<=t[j]) and (i>=s[j]) then  //在订单j的区间内
29                                         if r[i]-d[j]<0 then  //如果减去当前订单所需的教室数量小于0
30                                         begin
31                                                 if j<ans then  //如果小于ans,则更新ans
32                                                 begin
33                                                         ans:=j;
34                                                         break;
35                                                 end;
36                                         end
37                                         else
38                                                 r[i]:=r[i]-d[j];  //减去当前订单所需的教室
39                 end;
40         if flag then writeln('0')
41         else
42         begin
43                 writeln('-1');
44                 writeln(ans);
45         end;
46 end.

 

posted @ 2017-08-16 22:34  StupidJum  阅读(289)  评论(0编辑  收藏  举报