二分法的应用

梦想的初衷 提交于 2020-01-07 19:31:40

今天学到的新知识集合

1.bool函数可以直接对变量进行操作而且返回值为0.1;

如下面这个代码就可以看到没有输入a[i]的形参但是仍然可以对其进行操作

return 后面的语句为真就返回1

否则返回0

所以用于if(judge(k))判断是可以的

bool judge(const int &len)  // 用于判断的 子函数
{
    long long cnt=0;          //部分情况可能爆int
    for (int i=0;i<n;i++)
        cnt+= (long long)(a[i]/len);
    return cnt>=k;
}

2.关于二分法

二分法的最简单形式就是区间的取换

目前我觉得难点在于判断条件

今天做了几道二分题

感觉自己是个菜鸡

第一题就是练手的模板题

用于弄清楚二分法的概念

#include <iostream>
#include<bits/stdc++.h>
using namespace std;

int n,x,i,mid,t,w;
const int N=2000005;
int a[N];
int main()
{
    while(~scanf("%d %d",&n,&x))
    {
        for(i=0;i<n;i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
        t=0;w=n-1;
        while(t<=w)
        {
            mid=(t+w)/2;
            if(a[mid]==x)
                break;
            else
                if(a[mid]>x)
                w=mid-1;
                else
                    if(a[mid]<x)
                    t=mid+1;
        }
        if(a[mid]==x)
        printf("%d\n",mid+1);
        else
            printf("%d\n",mid);
    }
    //cout << "Hello world!" << endl;
    return 0;
}

写完这题之后就可以直接用c艹内置的取下标函数了

#include <iostream>
#include<bits/stdc++.h>
using namespace std;
const int N=2000006;
int a[N];
int n,x;
int t,w,mid;
int main()
{
    while(~scanf("%d%d",&n,&x))
    {
        for(int i=0;i<n;i++)
            scanf("%d",&a[i]);
        sort(a,a+n);
     printf("%d\n",upper_bound(a,a+n,x)-a);

    }
    //cout << "Hello world!" << endl;
    return 0;
}

然后就是神奇的桶排序,居然出现在了二分的题了= =

(超时问题一直是心里不可言说的痛苦

小清新又要使坏了,他发现二倍问题(Problem 8)并不能难住大家,于是他决定悄咪咪的改一波数据。
于是:
给定2到10,000个不同的正整数,你的任务是计算这些数里面有多少个数对满足:数对中一个数是另一个数的两倍。比如给定1 4 3 2 9 7 18 22,得到的答案是3,因为2是1的两倍,4是2个两倍,18是9的两倍。

Input

输入包括n组测试数据。第一行一个正整数 n 。
接下来n行表示n组数据,每组数据为一行,给出2到10,000个两两不同且小于100,000的正整数。每一行最后一个数是0,表示这一行的结束后,这个数不属于那2到10,000个给定的正整数。

Output

对每组输入数据,输出一行,给出有多少个数对满足其中一个数是另一个数的两倍。

Sample Input

3
1 4 3 2 9 7 18 22 0
2 4 8 10 0
7 5 11 13 1 3 0

Sample Output

3
2
0对于这道题我的感想就是删多组删多组= =;
#include <iostream>
#include<bits/stdc++.h>
using namespace std;
int n;
const int N=10002;
const int K=2000005;
int a[N],pai[K];
int i,j,temp,ans,zu,k;
int main()
{      scanf("%d",&zu);
        for(i=0;i<zu;i++)
        {
            k=0;ans=0;
            memset(pai,0,sizeof(pai));
            while(scanf("%d",&temp)&&temp)
            {
                a[++k]=temp;
                pai[temp]++;;
            }
            for(j=1;j<=k;j++)
            {
                if(pai[2*a[j]]!=0)
                    ans++;
            }
            printf("%d\n",ans);
        }


    //cout << "Hello world!" << endl;
    return 0;
}

后面的题我都觉得难= =

好难

思路都有就是都RE

憋屈

烦到写不下去了

先随便粘代码后面补上

#include <bits/stdc++.h>
using namespace std;
const double pi=acos(-1.0);
int h;
int check(double r)
{
    if (pow(r,pi)>=h*(pi*r*r-r))
        return 1;
    else
        return 0;

}

int main()
{
    //ios::sync_with_stdio(false);
    int t;
    double l,r,mid;
    scanf("%d",&t);
    while(t--)
    {
     scanf("%d",&h);

     l=0;r=100000;

     while(l<r)
     {
       mid=(l+r)/2.0;
      if (r-l<=1e-8) break;
       if (check(mid)==1) //mid大了
        r=mid;
       else
        l=mid;
     }
      printf("%.4lf\n",mid);

     }


    return 0;
}
#include <iostream>
#include<bits/stdc++.h>
#include<math.h>
const double pai=acos(-1.0);
int zu,h;
double v1,v2;
double r;
double temp,i,j,mid,t;
using namespace std;
int judge(double r)
{
    if (pow(r,pai)>=h*(pai*r*r-r))
        return 1;
    else
        return 0;

}

int main()
{
    scanf("%d",&zu);
    while(zu--)
    {

        scanf("%d",&h);
        t=0;r=100000;
        while(t<r)
        {
             mid=(t+r)/2;
            if(r-t<=1e-8)
            break;
            if(judge(mid))
                r=mid;
            else
                t=mid;

        }
        printf("%.4f\n",r);
    }

    //cout << "Hello world!" << endl;
    return 0;
}
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#define double long long int
using namespace std;
const int maxn=1e5+10;
int n,k;
double a[maxn];
bool check(double x)
{
    int cnt=0;
    for(int i=0;i<n;i++)
        cnt+=(int)(a[i]/x);
    return cnt>=k;
}
int main()
{
    scanf("%d%d",&n,&k);
    for(int i=0;i<n;i++)
        scanf("%lf",&a[i]);
    double eps=1e-6;
    double l=0.0,r=0x3f3f3f3f;
    while(r-l>eps)
    {
        double mid=l+(r-l)/2.0;
        if(!check(mid))
            r=mid;
        else
            l=mid+eps;
    }

    printf("%lld\n",(floor(r*100)/100.0));
    return 0;
}

 

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!