独木桥p1007

题意:

给定长度L的轴,轴上有n个点,n个点可以向左右走,左到0,右到L+1,且两个点如果相向而走,碰面后都会转身离开

问这些点全部离开独木桥所需的最大和最小时间(每个点运动的速度为1m/s)

分析:

1,简单模拟题,最小的话,我想的是对每个点到桥两边距离取最小,之后再对这些值取最大即可;

2,这题比较有意思,刚开始我分析这个题选取最大是用最左边的点和最右边的点,他们遇到之后再相互转身离开,这样二者取最大,但是会wa一个点

其实,相互转身离开可以看作是两个点交换灵魂之后继续向前走,因为他们的速度都没有变化,所以只需要对每个点到两边的距离取最大值即可。

反思:

1,从我的错误想法看,如果两个点中间距离为偶数,这样想应该是不会出错,但如果是奇数就牵扯到把一个长度为1的格子分成两个处理,这样处理起来会很麻烦;

2,显然把他们抽象成交换灵魂就会很好理解,直接取一个最大值即可。

3,遇到这种简单模拟题,从我自己的惯性思路来说,总是喜欢硬生生的模拟,如果模拟的条件很多的话,容易写题写自闭,有时候和答案仅仅一步之遥......很难将这种问题抽象为某一个很简单的式子,再看完别人的代码之后,有种我为什么这么蠢的感觉,不仅仅是这一个问题,还有cf比赛时候,总是将简单的问题复杂化,可能是因为还没有养成这种算法思维,慢慢积累吧。

代码:

1,错误版本,会wa第一个点,其他点都会过,有时间改改(逃

#include<bits/stdc++.h>
const int maxn=5e3+10;
const int inf=0x3f3f3f3f;
typedef long long ll;

using namespace std;
int a[maxn];

int main()
{
  int L,n;
  cin>>L>>n;
  int ma=0,mi=0;
  for(int i=1; i<=n; i++)
  {
    cin>>a[i];
    mi=max(mi,min(L+1-a[i],a[i]-0));
  }
  sort(a+1,a+1+n);
  int tmp=(a[n]-a[1])/2;
  int ans=a[n]-tmp;
  int ans1=a[1]+tmp;
   ma=max(max(L+1-ans1,ans1),max(L+1-ans,ans));
  cout<<mi<<" "<<ma+tmp<<endl;
}

2,正确版本

#include<bits/stdc++.h>
const int maxn=5e3+10;
const int inf=0x3f3f3f3f;
typedef long long ll;

using namespace std;
int a[maxn];

int main()
{
  int L,n;
  cin>>L>>n;
  int ma=0,mi=0;
  for(int i=1; i<=n; i++)
  {
    cin>>a[i];
    mi=max(mi,min(L+1-a[i],a[i]-0));
    ma=max(ma,max(L+1-a[i],a[i]-0));
  }
  cout<<mi<<" "<<ma<<endl;
}

 

posted on 2020-09-30 00:46  mmn  阅读(184)  评论(0)    收藏  举报