CQYZ_Vijos_P3090 赛车游戏

【问题描述】

  小沐最近迷上一款赛车游戏,游戏是这样滴!
游戏中给出n辆赛车和一条无限长的公路。每辆车均在道路上有各自不同的起点,也有各自的前进速度(赛车始终是匀速前进)。为了防止跑得快的车在超过跑得慢的车时发生碰撞,每局游戏前,小沐要把道路分成许多赛道,使得处在同一条赛道上的车在本局游戏中不会处在同一个位置。游戏一旦开始,车的赛道就不能再更换。
  一局游戏会持续T分钟,在一局中,小沐能获得的金币数量与赛道的数目成反比(当然在某种赛道设计方案中,如果游戏中发生了碰撞事故,则相应的罚没金币数量也是与赛道数量成反比的)。
  由于小沐还小,需要你来帮助进行赛道设计,以赢得尽量多的金币。

【输入格式】

  输入的第1行包含两个2个整数n和T,他们的意义如题目描述。接下来n行,每行2个整数,表示赛车的初始位置s(米)和速度v(米/分钟)。数据以s递增的顺序给出。

【输出格式】

  输出一个整数,表示在T分钟(包含第T分钟)的游戏中,至少需要多少条赛道。

【输入样例】

5 3
0 1
1 2
2 3
3 2
6 1

【输出样例】

3

【数据范围】

50%的数据满足:1<=n<=1000
100%的数据满足:1<=n<=100000,1<=T<=1000000000,0<=s<=1000000000 ,0

题解:

  贪心,维护每条赛道上跑的最远的车的终点road[i],由于数据已按s排好序,所以直接按顺序考虑每辆车放于哪个赛道就行了
  对于赛车i、j,当起点s[i] < s[i]且终点t[i]>t[j]时,可以判断i与j会相撞
  对于第i辆车,当前j-1条赛道不能满足条件而第j条满足时,应放在第j条赛道并更新road[j]=t[i]
  当没有赛道满足条件时,则单独放于新赛道中
  可以发现road数组是单调递减的,于是用二分查找赛道

  本来对于100%的数据,O(n^2)算法是过不了的,但是数据有随机性,ans最大在600左右,于是顺序查找水过。。。

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long ll;
const int maxn=100005;
struct data{
    ll s,t;
    friend bool operator<(data a,data b){
        if(a.s!=b.s) return a.s<b.s;
        return a.t<b.t;
    }
}car[maxn];
int cc=0;
ll n,t,road[maxn];
ll in(){
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-') f=-f;ch=getchar();}
    while(ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar();
    return x*f;
}
int main(){
    freopen("racing.in","r",stdin);
    freopen("racing.out","w",stdout);
    n=in(),t=in();
    ll s,v;
    for(int i=1;i<=n;i++){
        s=in(),v=in();
        car[i].s=s,car[i].t=s+v*t;
    }
    sort(car+1,car+n+1);
    bool ok;
    for(int i=1;i<=n;i++){
        ok=0;
        for(int j=1;j<=cc;j++) if(car[i].t>road[j]){    //顺序查找是错的!错的!错的!懒得改二分而已
            road[j]=car[i].t,ok=1;
            break;
        }
        if(!ok) road[++cc]=car[i].t;
    }
    printf("%d",cc);
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值