AC通道(
Uva
):
https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4196
PDF :https://uva.onlinejudge.org/external/14/1450.pdf
机场
Description
有一个客流量巨大的机场,却只有一条起飞跑道。
换句话说,每个时刻只能有一架飞机起飞(从
E
或者
在任一时刻,
E
通道和
(上图中,
你的任务是在每个时刻选择一架飞机起飞,使得任意时刻飞机的最大编号最小。
Input
输入的第一行为数据组数
T
。
每组数据的第一行为时刻总数
以下
n
行每行两个整数
Output
对于每组数据,输出飞机最大编号的最小值。
Sample Input
3
1
1 1
3
3 2
0 3
2 0
6
0 1
1 1
1 2
1 1
1 1
6 0
Output
0
3
5
Solution
显然二分答案。
现在就只需要解决判定性问题了。
即当这个最大编号为 x 时,满不满足条件。
因为题目中说,在一个时刻中,起飞一辆飞机。
我们无法判断到底是起飞哪个通道的飞机。
如果某个通道里面的飞机个数为
如果两个通道里面的飞机个数都不为 0 ,我们就先记下,这里起飞了一架飞机。
设起飞飞机
某一时刻,某个通道里面的飞机数如果大于了
x
,我们就要将它的飞机数改为
设
a
表示
若 Max{a−x,0}+Max{b−x,0}>m OR ai>x OR bi>x ,则不可能。
当 a=0 且 b≠0 时, b 减一(起飞一个飞机)。
否则,当
否则,当
Code
- #include <iostream>
- #include <cstdio>
- using namespace std;
- int T,n;
- int e[5010],w[5010];
- inline int mabs(int x){
- return x<0?0:x;
- }
- inline int in(){
- int ans=0;char x=getchar();
- while(x<‘0’||x>‘9’)x=getchar();
- while(x>=‘0’&&x<=‘9’){ans=ans*10+x-‘0’;x=getchar();}
- return ans;
- }
- bool pan(int x){
- int ss=0,ll=0,rr=0;
- for(int i=1;i<=n;i++){
- ll+=e[i];rr+=w[i];
- if(e[i]>x||w[i]>x)return false;
- if(mabs(ll-x)+mabs(rr-x)>ss)return false;
- if(!ll&&rr)rr–;
- else if(ll&&!rr)ll–;
- else if(ll+rr>ss)ss++;
- }
- return true;
- }
- int main(){
- scanf(”%d”,&T);
- while(T–){
- scanf(”%d”,&n);
- for(int i=1;i<=n;i++){e[i]=in();w[i]=in();}
- int l=1,r=100000;
- int ans=r;
- while(l<=r){
- int mid=(l+r)/2;
- bool flag=pan(mid);
- if(flag){
- if(ans>mid)ans=mid;
- if(r!=mid-1)r=mid-1;
- else break;
- }
- else{
- if(l!=mid+1)l=mid+1;
- else break;
- }
- }
- printf(”%d\n”,ans-1);
- }
- return 0;
- }