zoukankan      html  css  js  c++  java
  • NOIP 2015[D2 T1] 跳石头

    这里写图片描述
     

     
    看到这个题,想到了二分答案。用二分的方法枚举最小距离x,和前面石块之间距离(变化)大于这个距离的石块就去掉,把去掉的石块数和m作比较,来变换x,最后找到答案;
    但是,第一次写的时候,没有想到如果前面的石块被去掉,那么后面的石块在判断距离时,就会受到影响,并不是一成不变的。结果只得了10 fen ;
    Besides,写一个正确的二分是很困难的对我来说,因为我记好的板子有时对有时错。如果有大神对二分精通,很虔诚的向您请教。

    下面是ac代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<cmath>
    using namespace std;
    int len,n,m;
    int a[50009],d[50009]; 
    int check(int x)
    {
        int t=0,last=0;//last记录未被去掉的前一个石块的位置。
        for(int i=1;i<=n;i++)
        {
            if(a[i]-last<x) t++;//和前一个石块的距离比枚举的答案x小就去掉
            else last=a[i];
        }
        return t;
    }
    int main()
    {
        scanf("%d%d%d",&len,&n,&m);
        if(n==m){printf("%d",len);return 0;} 
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int l=1,r=len;
        while(l+1<r)
        {
            int mid=(l+r)>>1;
            if(check(mid)>m)
             r=mid;  //如果去掉的石块大于m,此时答案一定不可以,r=mid,所以最终的r一定不是答案就将答案x向小了枚举。
            else l=mid;
        }
        printf("%d
    ",l);//r一定不是答案,l一直向右逼近,最终到最优解。
        return 0;
    } 
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<vector>
    #include<queue>
    #include<cmath>
    using namespace std;
    int len,n,m;
    int a[50009],d[50009]; 
    int check(int x)
    {
        int t=0,last=0;
        for(int i=1;i<=n;i++)
        {
            if(a[i]-last<x) t++;
            else last=a[i];
        }
        return t;
    }
    int main()
    {
        scanf("%d%d%d",&len,&n,&m);
        if(n==m){printf("%d",len);return 0;} 
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
        }
        int l=1,r=len;
        while(l<=r)
        {
            int mid=(l+r)>>1;
            if(check(mid)<=m)
             l=mid+1;
            else r=mid-1;//mid是不符合的且偏大,向左移得到最优解
        }//因为要求的是满足的最大的,所以要从不满足且偏大的向左移一点点,如果符合,就是最优解了。
        printf("%d
    ",r);
        return 0;
    } 
  • 相关阅读:
    C#编写功能让你的系统导入注册表文件时不提示
    登陆框提示历史记录
    C# 操作系统防火墙
    C# 制作Java +Mysql+Tomcat 环境安装程序,一键式安装 (续集Tomcat 配置)
    C# 修饰符你记住了吗?
    C# 实现设置系统环境变量设置
    showModalDialog使用例子,父窗口向子窗口传递值
    C#后台无刷新页面弹出alert方法
    VS2008 无法启动调试.未安装Silverlight托管调试包 .
    在GridView中使用FindControl .
  • 原文地址:https://www.cnblogs.com/dfsac/p/7587912.html
Copyright © 2011-2022 走看看