大一寒假训练六(二分查找)(未完待续……)2020.1.5

今天的二分真的是有点玄学!!!但是兴安家族个陈宇老师提前拜了个早年,QAQ!Happy!!今天练习结束时间提前了,所以榜单有点难看~

 

Problem:A    二分查找

核心思路:题干中说按有序排列,直接暴力就ok。

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

int y;
int main()
{
    ios::sync_with_stdio(0);
    int n, x;
    while (cin >> n >> x)
    {
        int ans = 0;
        for (int i = 1; i <= n; i++)
        {
            cin >> y;
            if (x < y && !ans)
            {
                ans = i;
            }
        }
        cout << ans - 1 << endl;
    }
    return 0;
}

Problem:B    小清新的二分查找之旅

核心思路:十分基础的二分查找,注意审题。

#include <bits/stdc++.h>

using namespace std;
typedef long long LL;
const int M = 1e6;
LL a[M], b[M];

int main()
{
    //ios::sync_with_stdio(0);
    int n, q;
    while (~scanf("%d%d", &n, &q))
    {
        for (int i = 1; i <= n; i++)
            scanf("%lld", &a[i]);
        for (int i = 1; i <= q; i++)
            scanf("%lld", &b[i]);
        sort(a + 1, a + 1 + n);
        LL maxx = a[n];
        for (int i = 1; i <= q; i++)
        {
            int flag = 0;
            if (maxx < b[i])
                flag = 0;
            else
            {
                int head = 1, foot = n, mid = head + (foot - head) / 2;//防爆(再此题中没有用,可以养成习惯)
                while (head <= foot)    //手写二分
                {
                    if (a[mid] == b[i])
                    {
                        flag = 1;
                        break;
                    }
                    if (a[mid] < b[i]) //小的时候
                        head = mid + 1;
                    else               //大的时候
                        foot = mid - 1;
                    mid = head + (foot - head) / 2;
                }
            }
            if (flag)
                printf("no\n");
            else
                printf("YES\n");
        }
    }
}

Problem:C    小清新的函数坐标-二分

核心思路:实数型的二分,注意跳出的时间。

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

double f(double x)      //定义函数
{
    return 0.0001 * pow(x, 5) + 0.003 * pow(x, 3) + 0.5 * x - 3;
}
int main()
{
    double y;
    while (~scanf("%lf", &y))
    {
        double head = -1 * 20, foot = 20, mid = (foot + head) / 2;
        while (f(foot) - f(head) >= 1e-6)//确定合适的跳出范围,由于本博主水平有限,只能看脸了。
        {
            if (f(mid) > y) //大的时候
                foot = mid;
            else            //小的时候
                head = mid;
            mid = (foot + head) / 2;
        }
        printf("%.4lf\n", mid);
    }
    return 0;
}

Problem:D    小清新的二倍问题加强版-二分-桶排(NEFU 1647)

核心思路:可以用二分,也可以用桶排序。

方法一:桶排,制作计数器,记录数的有无。

#include <bits/stdc++.h>

using namespace std;
const int M = 1e5 + 5;
int num[M], flag[200010];
int main()
{
    ios::sync_with_stdio(0);
    int t;
    cin >> t;
    while (t--)
    {

        int tmp = 1;
        int x;
        long long ans = 0;
        memset(flag, 0, sizeof(flag));
        while (cin >> x)
        {
            if (x == 0)
                break;
            else
            {
                num[tmp] = x;
                flag[x] = 1;        //计数器    
                tmp++;
            }
        }
        tmp--;
        for (int i = 1; i <= tmp; i++)
        {
            if (flag[2 * num[i]])   //判断是否存在
                ans++;
        }
        cout << ans << endl;
    }
    return 0;
}

方法二:二分查找。

核心思路:利用upper_bound函数,直接返回坐标,再进行判断。

#include <bits/stdc++.h>

using namespace std;
const int M = 1e4 + 5;
int num[M];
int main()
{
    ios::sync_with_stdio(0);
    int n;
    cin >> n;
    while (n--)
    {
        int tmp1, ans = 0, x, tmp = 0;
        while (cin >> x && x)
            num[++tmp] = x;
        sort(num + 1, num + 1 + tmp);
        for (int i = 1; i <= tmp; i++)
        {
            tmp1 = upper_bound(num + 1, num + 1 + tmp, 2 * num[i]) - num - 1;//upper_bound函数返回第一个大于他的数坐标
            if (2 * num[i] == num[tmp1] || 2 * num[i] == num[tmp1 + 1])      //判断tmp1是否符合题干条件
                ans++;
        }
        cout << ans << endl;
    }

    return 0;
}

Problem:E    简单几何-二分(NEFU 1303)

#include <bits/stdc++.h>

using namespace std;
double h;
const double pi = acos(-1.0); //得到3.14.......
double judge(double r)        //定义函数
{
    if (pow(r, pi) >= h * (pi * r * r - r))
        return 1;
    else
        return 0;
}

int main()
{
    int t;
    scanf("%d", &t);
    while (t--)
    {
        double head = 0, foot = 1e5, mid;
        scanf("%lf", &h);
        while (foot > head)
        {
            mid = (head + foot) / 2.0;
            if (foot - head <= 1e-8) //这个是他玄学的地方,我也不知到为啥QAQ
                break;
            if (judge(mid)) //数值大,区分与整数型二分的赋值
                foot = mid;
            else //数值小
                head = mid;
        }
        printf("%.4lf\n", mid);
    }
    return 0;
}

 

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值