Bzoj3893 [Usaco2014 Dec]Cow Jog

本文解析了一道经典的算法题目——牛群赛跑问题。题目描述了一条无限长的单行跑道上有N头牛,每头牛有其初始位置和速度。随着时间推移,较快的牛会追上较慢的牛并形成群体。文章提供了有效的算法解决方案,并附带源代码,通过排序和遍历的方法确定最终形成的牛群数量。

 

Time Limit: 10 Sec  Memory Limit: 128 MB
Submit: 302  Solved: 157

Description

The cows are out exercising their hooves again! There are N cows jogging on an infinitely-long single-lane track (1 <= N <= 100,000). Each cow starts at a distinct position on the track, and some cows jog at different speeds. With only one lane in the track, cows cannot pass each other. When a faster cow catches up to another cow, she has to slow down to avoid running into the other cow, becoming part of the same running group. The cows will run for T minutes (1 <= T <= 1,000,000,000). Please help Farmer John determine how many groups will be left at this time. Two cows should be considered part of the same group if they are at the same position at the end of T minutes.
在一条无限长的跑道上有N头牛,每头牛有自己的初始位置及奔跑的速度。牛之间不能互相穿透。当一只牛追上另一只牛时,它不得不慢下来,成为一个群体。求T分钟后一共有几个群体。

 

Input

The first line of input contains the two integers N and T. The following N lines each contain the initial position and speed of a single cow. Position is a nonnegative integer and speed is a positive integer; both numbers are at most 1 billion. All cows start at distinct positions, and these will be given in increasing order in the input.

 

Output

A single integer indicating how many groups remain after T minutes.

 

Sample Input

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

Sample Output

3

HINT

 

Source

 

先按初始顺序给牛编号,然后让牛跑T分钟,按照新位置从小到大排序(位置相同的,序号大的在前)。

然后从前往后扫一遍,如果编号小的牛跑到的位置比编号大的牛远,那么实际上他们已经合并了。

记录从1开始的编号单增序列长度就是答案。

 

从别的博客(辗转山河弋流歌)看到了更短的写法:从后往前扫一遍,看哪些牛撞死了

 

 

 1 /*by SilverN*/
 2 #include<algorithm>
 3 #include<iostream>
 4 #include<cstring>
 5 #include<cstdio>
 6 #include<cmath>
 7 #define LL long long
 8 using namespace std;
 9 const int mxn=100010;
10 LL read(){
11     LL x=0,f=1;char ch=getchar();
12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
14     return x*f;
15 }
16 LL v[mxn],p[mxn];
17 LL id[mxn];
18 int n;LL T;
19 int cmp(int a,int b){
20     if(p[a]==p[b])return a>b;
21     return p[a]<p[b];
22 }
23 int main(){
24     n=(LL)read();
25     T=read();
26     int i,j;
27     for(i=1;i<=n;i++){
28         p[i]=read();v[i]=read();
29         p[i]+=v[i]*T;
30     }
31     for(i=1;i<=n;i++)id[i]=i;
32     sort(id+1,id+n+1,cmp);
33     int last=0,ans=0;
34     for(i=1;i<=n;i++){
35         if(id[i]>last){ans++;last=id[i];}
36     }
37     printf("%d\n",ans);
38     return 0;
39 }

 

转载于:https://www.cnblogs.com/SilverNebula/p/6044005.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值