前言
第一篇在洛谷过审的题解!!!
原题链接
一些胡言乱语
校模拟赛出了这道题,考场上推出来式子但是没有特判首尾,于是挂了 30。
另外,这仿佛是我在洛谷的第一篇题解。
题意
简化一下题意,实际上就是给定 n 个点,由这 n 个点引出斜率为 ±1 的直线,求所有交点的最大值。
以样例 1 为例:
如果按照刚刚写的理解方式,画成一个平面就是:

推式子
肯定是要循环写的。
设一个 A(di,hi),B(di+1,hi+1)。
待定系数法,先设穿过 A 的直线为 y1=x1+b1,求出来 b1=hi−di。
再设穿过 B 的直线为 y2=−x2+b2,求出来 b2=di+1+hi+1。
然后计算两直线交点,即 −x+di+1+hi+1=x+hi−di。
求出来 x=2di+1+hi+1+di−hi。
所以此时得到的最大值就是 2di+1+hi+1+di−hi+hi−di。
循环的时候去 max 即可。
本题还要求判断无解,那么什么时候无解呢?就是两个点连成一条直线的斜率大于 1 的时候,即 ∣di+1−dihi+1−hi∣>1 的情况。
另外首尾还需要特判一下。
AC 代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| #include <bits/stdc++.h> using namespace std; const int N=1e5+10; int n,m; struct node{ int d,h; }a[N]; int ans=-1; int main(){ scanf("%d%d",&n,&m); for(int i=1;i<=m;i++) scanf("%d%d",&a[i].d,&a[i].h); ans=a[1].d+a[1].h-1; for(int i=1;i<m;i++){ if(abs(a[i].h-a[i+1].h)>a[i+1].d-a[i].d){ printf("IMPOSSIBLE"); return 0; } ans=max(ans,max(a[i].h,a[i+1].h)+((a[i+1].d-a[i].d)-abs(a[i].h-a[i+1].h))/2); } ans=max(ans,a[m].h+n-a[m].d); printf("%d",ans); }
|