这个方法真的超简单,很精彩,求求看下去吧!!!
题目来源:洛谷
如需看题,请点击题目传送门。
作者精讲
这道题也不简单,本人看到之后直接就看了题解,结果依然很惨(“DP是啥啊???”)所以就有开始~自~己~写~。
说来也巧,我在CSDN上看到了这么一篇文章,里面说可以这么做:“那么我们就可以把所有士兵分开。首先,我们把他们一个个读进去。然后,对于每一个士兵,他有向左和向右两种选择。设士兵在位置p,如果向左,需要p时间单位;向右,需要L-p+1个。分别取max和min,更新答案即可。”所以我就按照这个方法写了写,结果还真就出来了,讲讲思路。
Step1. 读入(这个不用多说了吧)。
Step2. 读入时就可以把整道题的代码解决。
Step3. 读入的循环外定义两个变量,保存最小值和最大值。
Step4. 每次更新最小值和最大值。
- 最小值更新为在位置p向左走需要的时间(p)和向右走需要的时间(l+p-1)中取最小值,再和原来的最小值进行比较取其中的最大值。
- 我知道你~听~不~懂~所以精简一下,就是(p和l+p-1)的较小的那个和原来的最小值比。
- 变成代码就是min_time = max(min(x, l-x+1), min_time)。
- 最大值同理,更新为位置p向左走需要的时间(p)和向右走需要的时间(l+p-1)中取最大值,再和原来的最大值进行比较取其中的最大值。
- 我知道你还是~听~不~懂~所以精简一下再,就是(p和l+p-1)的较大的那个和原来的最大值比。
- 变成代码就是max_time = max(max(x, l-x+1), max_time)。
最后输出答案就可以了,整段代码才16行,去掉括号和空格13行。
最后的最后,来人,上代码!!!
#include <bits/stdc++.h>
using namespace std;
int main() {
int l, n;
cin >> l >> n;
int min_time = 0, max_time = 0;
for (int i = 0; i < n; i++) {
int x;
cin >> x;
max_time = max(max(x, l-x+1), max_time);
min_time = max(min(x, l-x+1), min_time);
}
cout << min_time << ' ' << max_time;
return 0;
}
作者痛苦的哀嚎:点赞关注收藏,点赞关注收藏,点赞关注收藏!!!
番外:题解里某些大佬的长长的代码。
#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
int a[5007];//存士兵的位置
void xuanxue1(int,int);//找最小时间
void xuanxue2(int,int);//找最大时间
int l,n,mi,ma;
bool fla=0;
int main()
{
int i;
scanf("%d%d",&l,&n);
for(i=1;i<=n;i++)
scanf("%d",&a[i]);//输入每个士兵的位置
xuanxue1(-1,5000);//因为有t=0的情况所以从-1搜起
return 0;
}
void xuanxue1(int x,int y)//找最小时间
{
if(y-x<1)//y==x
{
printf("%d ",y);
xuanxue2(-1,5000);//去找最大时间
}
else if(y-x==1)
{
if(fla)//if(fla)证明已搜过一次,输出
{
printf("%d ",y);
fla=0;
xuanxue2(-1,5000);
}
else fla++;
}
//二分的部分
int mid=(x+y)/2;
for(int c=1;c<=n;c++)
{
mi=min(a[c],l-a[c]+1);
if(mid<mi)//证明所求的最小时间>mid
xuanxue1(mid,y);
}
xuanxue1(x,mid);
//
}
void xuanxue2(int x,int y)
{
if(y-x<1)
{
printf("%d",y);
exit(0);//直接退出
}
else if(y-x==1)
{
if(fla)
{
printf("%d ",y);
exit(0);
}
else fla++;
}
int mid=(x+y)/2;
for(int c=1;c<=n;c++)
{
ma=max(a[c],l-a[c]+1);
if(mid<ma)
xuanxue2(mid,y);
}
xuanxue2(x,mid);
}`
整片终。