赛车

来源:互联网 发布:傲来网络 编辑:程序博客网 时间:2024/06/10 09:38

前言
“网上自古无娇娘,残花败柳一行行,偶有几对鸳鸯鸟,也是野鸡配色狼。”欢迎来到嘟嘟课堂。今天我们讲一道很好的暴力题——赛车。
题目描述
有N 个赛车手(编号为1..N)准备在高速公路上赛车,每个赛车手都会开着自己的赛车,第i个赛车的车速为S[i] 千米/小时,高速公路上一共有M个赛车道。
为了安全起见,每个赛车手都要遵循以下原则:同车道前面有X个赛车,这辆赛车的车速就会降低D*X千米/小时,当然不会降到0以下,所以车速应该max(S[i]-D*X, 0)。由于车距很大,所以即使后面的车比前面的车快,你也不用担心会发生碰撞。
高速公路上有一个最低限速L,凡是低于该速度的车不允许在高速上行驶的(注意:减速后的速度若低于L也不能在高速上行驶),现在请你来计算一共可以多少辆赛车在高速公路上行驶。
输入
第一行4个空格隔开的整数N, M, D, L;
第2~N+1行每行一个整数,其中第i+1行描述第i个赛车手驾驶赛车的起初车速。
输出
一个整数,表示最多可以在高速上行驶的赛车数量。
样例输入
3 1 1 5
5
7
5
样例输出
2
数据范围限制
30%的数据:N≤20,M=1;
60%的数据:N≤1000,M≤10;
100%的数据:1≤N≤50000,1≤M≤100,1≤S[i], L≤10^6,0≤D≤5000。
提示
选择一个速度为5的赛车和速度为7的赛车,让速度为5的在前面行驶,速度为7的在后面行驶,但它的实际行驶速度是为6。
思路
这道题就是一道很明显的暴力枚举模拟。(暴力大神嘟嘟老师带你飞!带你飞进垃圾堆!)这种题,先在草稿本上理清思路,再去打暴力。思路很简单,首先将所有赛车的速度排序,从小到大排,然后循环1到n的赛车放到m个赛道里。一开始我想到的是倒着放,现房最大的,可以放一放超时,但再想一想,虽然不TLE了,但绝对会WA。所以枚举赛车和赛道,如果这个赛道能放得下这个赛车的话,就将赛道和赛车指针都+1.如果不能,就换下一辆赛车。因为如果连这个赛道都放不下,那么后面的赛道的目前的赛车数量也跟这个赛道一样,这个赛道放不下,那么后面的肯定也放不下(有点复杂,理解一下)。接下来输出ans即可。
代码

uses math;var        a:array[1..50000] of longint;        b:array[1..100] of longint;        i,j,k,l,n,m,d,ans:longint;procedure sb(l,r:longint);var        i,j,k,p:longint;begin        i:=l;        j:=r;        k:=a[(l+r) div 2];        while (i<j) do        begin                while (a[i]<k) and (i<r) do inc(i);                while (a[j]>K) and (l<j) do dec(j);                if (i<=j) then                begin                        p:=a[i];                        a[i]:=a[j];                        a[j]:=p;                        inc(i);                        dec(j);                end;        end;        if (i<r) then sb(i,r);        if (l<j) then sb(l,j);end;begin        readln(n,m,d,l);        for i:=1 to n do readln(a[i]);        sb(1,n);        i:=1;        j:=1;        while true do        begin                k:=max(a[i]-d*b[j],0);                if (k>=l) then                begin                        inc(ans);                        inc(b[j]);                        inc(i);                        inc(j);                        if (j>m) then j:=1;                        if (i>n) then break;                end                else                begin                        inc(i);                        if (i>n) then break;                end;        end;        writeln(ans);end.