【COCI2008】猴子摘桃
阿新 • • 發佈:2019-02-09
Description
動物園內最受歡迎就是猴子了,因為它們除了能爬能跳外還會很多技能。其中A類猴子特別擅長爬樹摘桃,而B類猴子擅長把桃子掰成兩半。
A類猴子有N只,編號為1到N,B類猴子有M只,編號為1到M。A類猴子中的第K只摘到第一個桃子需要花費A_k秒,此後每B_k秒就能摘到桃子;B類猴子中的第K只掰開第一個桃子需要花費C_k秒,此後每D_k秒就能掰開一個桃子。
不幸的是,B類猴子非常具有侵略性,兩種猴子不能同時待在場地內,因此,園長必須在A類猴子摘完所有桃子後立刻把它們帶走,然後立刻讓B類猴子進園;同樣當B類猴子把所有桃子全部掰開後也不能待在場地內太久,因為它們之間也會發生衝突,所有園長將在B類猴子掰開所有桃子後立刻送走它們。
園長帶走猴子和猴子進園的速度非常快,時間忽略不計。
Alice非常喜歡看B類猴子掰桃子,告訴你表演的總時間,但不知道一共有多少個桃子,請你幫Alice計算B類猴子進入動物園的時刻。
Solution
二分答案,判斷在二分時間內摘的桃子與掰開的桃子的大小關係,從而調整下一次二分。
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 101
#define inf 1000000000
using namespace std;
int a[N][2];
int b[N][2];
int T,n,m;
bool check(int mid)
{
int t1=0,t2=0;
fo(i,1,n)
if(a[i][0]<=mid) t1+=1+(mid-a[i][0])/a[i][1];
fo(i,1,m)
if(b[i][0]<=T-mid) t2+=1+(T-mid-b[i][0])/b[i][1];
if(t1<=t2) return true;
return false;
}
int main()
{
freopen("3.in","r",stdin);
freopen("3.out","w",stdout);
cin >>T;
cin>>n;
fo(i,1,n) scanf("%d %d",&a[i][0],&a[i][1]);
cin>>m;
fo(i,1,m) scanf("%d %d",&b[i][0],&b[i][1]);
int l=1,r=T;
fo(i,1,30)
{
int mid=(l+r)/2;
if(check(mid)) l=mid;
else r=mid;
}
if(check(r)) cout<<r;
else cout<<l;
}