题解:P1007 独木桥
因为这道题我右边的高中生 tqc 没做出来,但是被我一番提醒之后做出来了,发篇题解纪念一下。
这道题的复杂之处在于处理转身的情况。如果我们暴力去模拟的话应该是能过的,因为数据范围极小。但是这道题有个特别简单的 \(O(n)\) 解法。如果我们把转身的两个人看成能互相穿过的会怎么样呢?
答案是可以这么做的。因为这两个人转身之后本质上是一模一样的东西的。举个例子:左边有个人 A 在 \(0\) 位置,右边有个人 B 在 \(n\) 位置,他们两个人相向而行。显然,他们相遇的地方是 \(\dfrac{n}{2}\)。在这里往后,A 改为向左走,B 改为向右走。时间为 \(2\dfrac{n}{2}=n\),而如果我们把这个玩意看成是可以穿过的话,A 就从 \(0\) 直接到 \(n\),B 同理,花费的时间也是 \(n\)!
所以这就很简单了,对于每个坐标 \(x_i\),它需要花费的最大时间就是 \(\max(x_i,L-x_i+1)\),最小时间就是 \(\min(x_i,L-x_i+1)\)。最终的最大值就是 \(\max_{i=1}^n \max(x_i,L-x_i+1)\),最小值就是 \(\max_{i=1}^n \min(x_i,L-x_i+1)\)。
时间复杂度 \(O(n)\),可以边输入边处理,所以 \(n\) 其实可以开到 \(10^8\)。
AC 代码:
#include <iostream>
#define int long long
using namespace std;
signed main()
{
int l,n;
cin>>l>>n;
int maxn = 0,minn = 0;
for(int i = 1;i<=n;i++){
int x;
cin>>x;
maxn = max(maxn,max(x,l-x+1));
minn = max(minn,min(x,l-x+1));
}
cout<<minn<<' '<<maxn;
return 0;
}