题目链接https://www.luogu.org/problemnew/show/P1007
题目大意:有一座长为L的桥,其坐标为1…L,桥上有n个士兵,其坐标已知,每个士兵的速度都为1,方向未知。要求所有士兵都离开独木桥的最短和最长时间。
分析:所有士兵都必须离开桥。思路借鉴《训练指南》的一道题“蚂蚁”,两只蚂蚁碰撞掉头继续走,看上去和对穿而过没有区别。士兵也一样,不考虑两个士兵具体哪个是哪个,两人相当于一直向原方向走,碰撞可看作一直走但在左的还在左,在右的还在右,全局可以这样考虑。对于每个士兵,其最优为向近的端点一直走,最劣为向远的端点一直走。最短时间即为最靠近桥中间的人走到较近端点的时间,他是最后一个到端点的士兵,最远时间为最靠近桥端点的人走到另一端的时间,他是最后一个离开桥的士兵。
注意n=0的边界情况。
ps 一道难度为普及-,代码10+行的题都没有一次性A掉,还是第二天才A掉,看来要恢复到高二时的水平任重而道远…
o(nlogn)
#include<cstdio>
#include<algorithm>
using namespace std;
int l,n,a[5005];
int minn,maxx;
int main()
{
scanf("%d%d",&l,&n);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)minn=max(minn,min(a[i],l+1-a[i]));
if(n>0)maxx=max(l+1-a[1],a[n]);
printf("%d %d\n",minn,maxx);
return 0;
}
o(n)
#include<cstdio>
#include<algorithm>
using namespace std;
int l,n,a[5005];
int minn,maxx;
int main()
{
scanf("%d%d",&l,&n);
for(int i=1,pos;i<=n;i++){scanf("%d",&pos);a[pos]=1;}
for(int i=1;i<=l;i++)if(a[i]){maxx=l+1-i;break;}
for(int i=l;i>=1;i--)if(a[i]){maxx=max(maxx,i);break;}
for(int i=l/2;i>=1;i--)if(a[i]){minn=i;break;}
for(int i=l/2+1;i<=l;i++)if(a[i]){minn=max(minn,l+1-i);break;}
printf("%d %d\n",minn,maxx);
return 0;
}