二分思维实践

例题1:

二分思维实践

 

 1,这题第一思想其实就是用枚举,但是这个题目的数据规模太大了,所以肯定不能否则复杂度会达到百亿,这种规模一般来说在所有的程序设计竞赛中是肯定过不了的。但是这个思维也说一下把,其实就是用两次循环,分开来遍历,如果相加为m的话,就ok了。

  2,其实就是先对数组进行排序。先找到一个数,剩下一个数就是m-a[i],这个数用二分查找在这个数组中找。

  3,这种解法是把i指向头,j指向尾。把a[i]+a[j]与m进行比较,如果m大的话,就把i++,如果小的话就把j++。

例题2:

题目描述 : 农夫john建造了一座很长的畜栏,它包括N(2<=N<=100000)个隔间,这些小隔间的位置为x0,…,xn-1(0<=xi<=1000000000,均为整数,各不相同)。
john的C(2<=C<=N)头牛每头分到一个隔间。牛都希望互相离得远点省得互相打扰。怎样才能使任意两头牛之间的最小距离尽可能的大,这个最大的最小距离是多少呢?
思路与想法:

  这题第一个想法肯定是用暴搜啊,但是一看n的规模心凉了半截,估计没戏了。还有一个想法就是尽可能大,emmm能不能用贪心找到局部最优解呢?我感觉应该有戏但是没认真思考(懒死了)。

 暴搜的思维:首先只要能够在这个D下可以把所有的牛都放到隔间里面就ok了。首先隔间之间最大距离是1000000000/C。从1000000000/C到1进行枚举,所找到的第一个D满足题意的就是题目的解。

  尝试的方法:首先把第一条牛放在x0位置,第k个牛放在xi,第k+1条牛放在(xj+D,1000000)之间。如果找不到的话就把D--。再次尝试。如果所有的牛都能放得下的话就是了。当时这样的话都到100亿了肯定不行啊。所以这题用二分的思维。

  二分思维实践

 

#include <iostream>
using namespace std;
int n;
int c;  
cowstall = [100000000];
bool isok(int d){
    int cnt = 1;//注意第一个位置有一条牛 
    temp = cowstall[0];
    for(int i = 0;i<n;i++){
        if(cowstall[i] - temp > d){
            cnt++;
            tempstall = cowstall[i];
            //一定要记住上一条牛的位置。 
        }
    }
    if(cnt>=c){
        return true;
    }else{
        return false;
    }
}
int main(){
    cin>>n>>c;
    for(int i = 0;i<N;i++){
        cin>>cowstall[i];
    }
    int left = 0;
    //注意这个right是坐标值不是位置 
    int right = cowstall[n-1] - cowstall[0];
    while(left<right){
        int mid = left+(right-left)/2;
        if(isok(mid)){
            left = mid+1;
        }else{
            right = mid;
        }
    }
}

这个代码自己写还真不是那么容易写出来,注意一下什么是坐标体会一下枚举和二分的思维和思想。如何一步步简化代码。

 因最近自己在学python所以附上网络上看来的python代码:

N = (int)(input())
C = (int)(input())
cow_stall = []
for i in range(N):
    cow_stall.append((int)(input()))
cow_stall.sort()
def isok(distance):
    count = 1
    tempStall = cow_stall[0]
    for i in range(1,N):
        if(cow_stall[i]-tempStall>=distance):
            count += 1
            tempStall = cow_stall[i]
    if(count>=C):
        return True
    else:
        return False

def SearchMaxD():
    left = 0
    right = cow_stall[-1]-cow_stall[0]
    while(left<right):
        mid = (int)((left+right)/2)
        if(isok(mid)):
            left = mid+1
        else:
            right = mid
    print(mid)
    
SearchMaxD()
原文链接:https://blog.csdn.net/matafeiyanll/article/details/104862345

 

 

 

   

 

上一篇:一个 zkgui 挂掉的原因


下一篇:mysql数据库基础知识