斑羚飞渡
作者:互联网
题目描述
题目背景
两个人之间只能有一个活着 ,这必然是我和你的战争——Harry Potter
题目描述水宝宝在看完《斑羚飞渡》这本书后,突发奇想,想到了一个有趣的问题
现在峡谷的这边有n只斑羚,每只斑羚跳跃的最远距离为x[i],斑羚在别人的背上起跳的最远距离为y[i],峡谷的两岸的距离为s,问在最好情况下,有几只斑羚可以用别人的背当跳板跳到对岸,但由于斑羚的先天原因(主要是太肥),只能把别人当跳板一次
输入描述:
输入格式:
第一行n,s 接下来n行,每行2个整数代表x[i],y[i]
输出描述:
输出格式:
一行一个整数,表示有几只斑羚可以用别人的背当跳板跳到对岸
示例1
输入
5 10 6 8 2 100 7 3 1 10 2 5
输出
2
说明
第一组是第三只斑羚跳6的距离,第一只斑羚跳6的距离后从第三只的背上起跳,再跳8的距离后到达对岸
第二组是第五只跳2的距离,第二只跳2的距离后从第五只的背上起跳,跳100的距离到达对岸(假设对岸无限长,不可能跳出对岸)
备注:
对于100%的数据,n<=1000000;
对于所有数据,s<=1000000000; x[i],y[i]<=s; 不保证x[i]<y[i]
该题要想清楚了,就set什么的t都不要。
首先能自己跳过去的斑羚就在输入时计数,而且不存入。
(1)在是经别人帮助能跳可能过去的(x+y>=s)只需要读入y
别人帮忙也跳不过去的只需要读入x。
下面给出(1)的证明:
1)别人帮忙也不行的肯定只能帮别人了,它的y我们不关注,只需要关注,它的x1和需要他帮助的y2,只要它能满足x1+y2>=s,那在跳第一步的时候只需要都跳s - y2即可(被帮助的肯定能跳那么远,毕竟x2+y2>=s)
2)当不可能过去的将能帮的都帮了之后,可能还剩有人帮能过去的斑羚能过去(不止一只,一只自己过不去),他们还能过去⌊(剩余的有机会过去的斑羚数量)/2⌋只。
2) 证明:对于任意两只斑羚,他们的自身跳的距离x1,x2必定有,一个大于等于一个。当x1<=x2时,x2当踏板,两只同时跳x1远,第一只再踩一下第二只过去了。反之第二只就过去了。所以两两任意组合都能过去一只。所以最少过去它们的一半。所以此时与它们的x,y都无关。
上代码(set版,就代码操作比较简单,并不是上文讲的,这个没啥好讲的):
#include"iostream"
#include"set"
#include"cstdio"
#include"algorithm"
#define maxn 1000000+5
using namespace std;
typedef long long ll;
ll read(){
ll s = 0,w = 1;
char c = getchar();
while(c >'9'||c <'0'){w*=-1;c = getchar();}
while(c>='0'&&c <='9'){s = s*10 +c-'0';c=getchar();}
return w*s;
}
typedef struct BL{
ll x,y;
bool operator <(const BL a)const
{
if(y!=a.y)
return y<a.y;
return x<a.x;
}
}BL;
BL D[maxn];
bool b[maxn];
int main(){
multiset<int> a;
ll n,s,X,Y,cnt = 0,ans = 0,Num = 0;
n = read();s = read();
for(int i = 0;i < n;i++){
X = read();Y = read();
if(X>=s){
ans++;
continue;
}
else{
if(X+Y>=s){
D[cnt].x = X;
D[cnt].y = max((ll)1,s - Y);
cnt++;
}
else{
a.insert(X);
}
}
}
sort(D,D+cnt);
multiset<int> ::iterator it;
for(int i = 0;i < cnt;i++){
it = a.lower_bound(D[i].y);
if(it!=a.end()){
ans++;
a.erase(it);
}
else{
Num++;
}
}
ans +=Num/2;
cout <<ans;
}
普通的没有用set是上文写的那种
include<stdio.h>
#include<algorithm>
#define int long long
using namespace std;
int y[1000005],x[1000005];//a,c 可能跳过去的,b 一定不能跳过去的
bool cmp(int p,int q)
{
return p>q;//降序
}
signed main(){
int n,l;
int X,Y,j=0,k=0,ans=0;
scanf("%lld%lld",&n,&l);
for(int i = 0 ; i < n ; i ++ )
{
scanf("%lld%lld",&X,&Y);
if(X>=l)
ans++;
else if(X+Y<l){
x[k++]=X;
}
else{
y[j++]=Y;
}
}
sort(x,x+k);
sort(y,y+j,cmp);
int f=0;
int i;
for(i = 0 ; i < j && f < k ; i ++ ){
int temp=y[i];
while( f < k ){
if(temp+x[f]>=l){
ans++;
f++;
break;
}
else f++;
}
}
if(i==j)
printf("%lld",ans);
else printf("%lld",ans+(j-i)/2);
return 0;
}
标签:cnt,++,斑羚,int,ans,飞渡,include 来源: https://blog.csdn.net/weixin_43751631/article/details/92207388