uva 10366 Faucet Flow
题意:
给出l和r,然后从l坐标到r坐标每隔两个位置有一个档板,给出挡板的高度,然后想(-1, 1)中间加水,问什么时候会溢出。
分析:
两边先找到距离(-1,1)最近的最大值L和R。接着比较两个L和R的大小,相等的话就可以比较(-l,L的下标)和(R的下标,r)两块的大小,所以这块的时间要乘2。如果两边不一般高的话,找到高的一边第一个比另一边最高的那个高的p,然后比较a = ( p,Max(R,L)的下标)和b = (Min(R,L)的下标,end)的大小,然后决定是2*b还是a+b。细节各种烦人。
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=1005;
int l,r,x[maxn],y[maxn];
int L,R,idl,idr;
int pai(int a,int b)
{
if(a<=b)
return 2*a;
else
return a+b;
}
int solve()
{
int i;
l=(-l)/2;
r=r/2;
if(R==L)
{
int k=0,t=0;
int tmp=x[l];
for(i=l;i>idl;i--)
{
k+=tmp;
tmp=max(tmp,x[i-1]);
}
tmp=y[r];
for(i=r;i>idr;i--)
{
t+=tmp;
tmp=max(tmp,y[i-1]);
}
return (idl+idr+1)*R*2 +min(k,t)*2*2;
}
else
{
int T=min(R,L);
int p,q,k,t;
p=q=k=t=0;
while(p<l&&x[p]<T)
p++;
while(q<r&&y[q]<T)
q++;
if(R>L)
{
int tmp=y[q];
for(i=q;y[i]<=L;i++)
{
k+=tmp;
tmp=max(tmp,x[i-1]);
}
tmp=x[l];
for(i=l;i>p;i--)
{
t+=tmp;
tmp=max(tmp,x[i-1]);
}
}
else
{
int tmp=x[q];
for(i=p;x[i]<=R;i++)
{
k+=tmp;
tmp=max(tmp,x[i+1]);
}
tmp=y[r];
for(i=r;i>q;i--)
{
t+=tmp;
tmp=max(tmp,y[i-1]);
}
}
int ans=t>k?t+k:2*t;
return ans*2+(p+q+1)*T*2;
}
}
int main()
{
while(scanf("%d%d",&l,&r)!=EOF&&l&&r)
{
int i;
R=L=0;
for(i=l;i<=r;i+=2)
{
if(i<0)
{
scanf("%d",&x[(-i)/2]);
if(L<=x[(-i)/2])
{
L=x[(-i)/2];
idl=(-i)/2;
}
}
else
{
scanf("%d", &y[i/2]);
if(R<y[i/2])
{
R=y[i/2];
idr=i/2;
}
}
}
printf("%d\n",solve());
}
}