主要就是模拟这题,实在是比较坑,个人代码写的很长,很无奈。
大体要分情况讨论:
1: 确定最终从哪一边流出,也就是先确定左边最高的板子和右边最高的板子哪一个更高。 如果相同高度的话就是左右两边都可能流出,那就取时间最短的那个。
2:还有很多小细节,这个要自己做的时候慢慢想,做这种题还是很考验耐心的,因为没有什么算法,这也就不赘述了,具体过程还是自己慢慢体会吧。
留个纪念,纪念这个坑。
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<map>
using namespace std;
map<int,int> op;
int l,r;
int main()
{
while(scanf("%d %d",&l,&r) != EOF)
{
if(l==0&&r==0)break;
//op.clear();
int ll = l;
int rr = r;
int tmp;
int maxl = 0;
int maxr = 0;
int tmpl = -1;
int tmpr = 1;
while(ll<=r)
{
scanf("%d",&tmp);
op[ll] = tmp;
ll += 2;
}
ll = -1;
rr = 1;
while(rr <= r)
{
if(op[rr]>=maxr){maxr=op[rr]; tmpr = rr;}
rr += 2;
}
while(ll>=l)
{
if(op[ll]>=maxl){maxl=op[ll];tmpl = ll;}
ll -= 2;
}
int v = 0;
if(maxl > maxr)// 肯定右边流出
{
int v1=0, v2=0;
// 更新左边,
for(int ww=-1; ww>=l; ww -= 2)
{
if(op[ww] >= maxr){maxl = op[ww]; tmpl = ww; break;}
}
if(maxl!=maxr){
v = maxr*(tmpr-tmpl); // tmpl ,maxl 不变
maxr = 0;
int pre;
while(tmpr < r)
{
pre = tmpr;
maxr = 0;
for(int w = tmpr+2; w<=r; w += 2)
{
if(op[w] >= maxr){maxr = op[w]; tmpr = w;}
}
v += maxr*(tmpr-pre);
if(tmpr==r) break;
}
cout << v << endl;}
else if(maxl==maxr)
{
for(int ww=1; ww<=r; ww +=2)
{
if(op[ww]==maxr){tmpr=ww;break;}
}
v1 = maxr*(tmpr-tmpl); // tmpl ,maxl 不变
int v11 = 0;
maxr = 0;
int pre;
int ok = min(tmpr,-tmpl);
//tmpr = ok;
while(tmpr < r)
{
pre = tmpr;
maxr = 0;
for(int w = tmpr+2; w<=r; w += 2)
{
if(op[w] >= maxr){maxr = op[w]; tmpr = w;}
}
v11 += maxr*(tmpr-pre);
if(tmpr==r) break;
}
//tmpl = -ok;
int aa,bb;
for(int i=tmpl-2; i>=l; i -= 2)
{
if(op[i] > maxl){aa=op[i],bb=i;break;}
}
int chucun = (tmpl-bb)*(maxl);
if(chucun >= v11)
{
cout << v1 + v11*2 << endl;
}
else if(chucun < v11)
{
cout << v1 + chucun*2 + (v11-chucun) << endl;
}
}
}
else if(maxl < maxr) // 肯定从左边流出
{
//更新右边
int v1,v2;
for(int ww=1; ww<=r; ww+=2)
{
if(op[ww]>=maxl){maxr=op[ww];tmpr=ww;break;}
}
if(maxl != maxr)
{
v = maxl*(-tmpl+tmpr); // tmpr, maxr 不变;
maxl = 0;
int pre;
while(tmpl > l)
{
pre = tmpl;
maxl = 0;
for(int w=tmpl-2; w>=l; w -= 2)
{
if(op[w] >= maxl){maxl = op[w]; tmpl = w;}
}
v += (pre-tmpl)*maxl;
if(tmpl==l)break;
}
cout << v << endl;
}
else if(maxl==maxr)
{
for(int ww=-1; ww>=l; ww -= 2)
{
if(maxl==op[ww]){tmpl=ww;break;}
}
v1 = maxl*(tmpr-tmpl); // tmpr, maxr 不变;
int ok = min(-tmpl,tmpr);
int v11 = 0;
maxl = 0;
int pre;
//tmpl = -ok;
while(tmpl > l)
{
pre = tmpl;
maxl = 0;
for(int w=tmpl-2; w>=l; w -= 2)
{
if(op[w] >= maxl){maxl = op[w]; tmpl = w;}
}
v11 += (pre-tmpl)*maxl;
if(tmpl==l)break;
}
//tmpr = ok;
int aa,bb;
for(int i=tmpr+2; i<=r; i += 2)
{
if(op[i] > maxr){aa=op[i],bb=i;break;}
}
int chucun = (bb-tmpr)*(maxr);
if(chucun >= v11)
{
cout << v1 + v11*2 << endl;
}
else if(chucun < v11)
{
cout << v1 + chucun*2 + (v11-chucun) << endl;
}
}
}
else if(maxl == maxr)
{
for(int ww=1; ww<=r; ww += 2)
{
if(op[ww]==maxl){tmpr=ww;break;}
}
for(int ww=-1; ww>=l; ww -= 2)
{
if(op[ww]==maxr){tmpl=ww;break;}
}
v = (tmpr-tmpl)*maxl; // 所有都变。
// cout << tmpr << " " << tmpl << endl;
int vl = v;
int vr = v; // 两边各走一遍,选最小的
// 右边走
//int cccc = maxr;
maxr = 0;
int pre;
while(tmpr < r)
{
pre = tmpr;
maxr = 0;
for(int w = tmpr+2; w<=r; w += 2)
{
if(op[w] >= maxr){maxr = op[w]; tmpr = w;}
}
vr += 2*maxr*(tmpr-pre);
if(tmpr==r) break;
}
// 左边走
//maxr = cccc;
maxl = 0;
int pre2;
while(tmpl > l)
{
pre2 = tmpl;
maxl = 0;
for(int w=tmpl-2; w>=l; w -= 2)
{
if(op[w] >= maxl){maxl = op[w]; tmpl = w;}
}
vl += 2*(pre2-tmpl)*maxl;
if(tmpl==l)break;
}
//cout << vl << " " << vr << endl;
cout << min(vl,vr) << endl;
}
}
return 0;
}
水波.