zoukankan      html  css  js  c++  java
  • 独木桥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;
    }
  • 相关阅读:
    @@IDENTITY,SCOPE_IDENTITY和IDENT_CURRENT的辨析
    Blue Jeans[poj3080]题解
    绿色通道题解
    后缀数组
    Power Strings[poj2406]题解
    KMP算法
    Life Forms[poj3294]题解
    STM32固件库文件编程结构思想的理解
    GPIO设置
    HTML_v2
  • 原文地址:https://www.cnblogs.com/sweetlittlebaby/p/13752583.html
Copyright © 2011-2022 走看看