二分算法小练习

本文解析了四道牛客编程题,涉及解方程、数论应用、二分查找技巧以及完全平方数判断,展示了在实际编程竞赛中的解题策略和C++代码实现。
摘要由CSDN通过智能技术生成

牛客上的题

直接题号加ac码

1.题号14416 解方程

O(n2log(n))

#include <bits/stdc++.h>
using namespace std;
int  a[1010];
int  fun(int a, int b, int c,int x)
{
    return a*x*x + b*x + c;
}
int main()
{
    int n , x;
    cin>>n >> x;
    for(int i = 0;i < n ;i++)cin >> a[i];
    
    sort(a, a + n);
    for(int i = 0; i < n;i++)
    {
        for(int j = 0; j < n; j++)
        {
            int l = 0 , r = n - 1;
            while(l<r)
            {
                int  mid = l+r>>1;
                if(fun(a[i],a[j],a[mid],x)>=0)r = mid;
                else l = mid + 1;
            }
            if(fun(a[i],a[j],a[l],x) ==0)
            {
                cout<<"YES";return 0;
            }
        }
    }
    cout<<"NO";
    return 0;
    
}

2.题号14675 圣诞节唐果

这个题目标着二分,其实不是二分,是数论的题
题目意思:数组中找两个数求和对p取模,求最大值
(a*b)%c = ((a%c)(b%c)) % c
(a+b)%c = ((a%c) + (b%c)) % c
多说一句,高中数学竞赛葛军那本书里有知识点

回到这个题
有两个小于p的数a,b,分两种情况看(a+b)%p
1.a+b < p ,当a || b 增大是(a + b) % p 增大
2.a+b >= p 同理a || b增大时(a + b) %p 增大
结合来看就是 / / 的图像 (抽象艺术)

#include <bits/stdc++.h>
using namespace std;
const int N =  2e5 + 10;
int a[N], T ;
int main()
{
    cin>> T;
    while(T--)
    {
        int n ,p;
        cin>> n>> p;
        for(int i = 0 ; i < n; i++)
        {
            cin>>a[i];
            a[i] %= p;
        }
        sort(a,a + n);
        int Max = (a[n-1]+a[n-2])%p;
        for(int i = 0 , j = n - 1; i < j; i++)
        {
            while(a[i] + a[j] >= p)j--;
            if(i < j)
            {
                Max = max(Max ,a[i] + a[j]);
            }
        }
        cout<<Max<<endl;
    }
    return 0;
}

3.题号14647一生之敌

不好评价的题,描述的一点不清楚,还只有一个测试点,注意数据范围,二分尽量写最直接的性质,我写成< n 就过不去测试点了
第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(昆明)。。。

#include <bits/stdc++.h>
using namespace  std;
typedef unsigned long long LL;
const LL N = 1357209;
LL T,n;
int main()
{
    cin>>T;
    while(T--)
    {
        LL n;
        cin>> n;
        LL l = 0 ,r = N;
        while(l < r)
        {
            LL mid = l + r  >> 1;
            if((mid*2 *(2*mid*mid+1)) >= n)r = mid ;
            else l = mid + 1;
        }
      cout<<r*2*(2*r*r + 1)<<endl;
    }
}

4.14733完全平方数

这个题有点恶心,卡了我好久,正常思路是你在数组里找到l, r的位置,然后用下标相减
我找的不熟练,卡了,最后处理结果也有细节
正常 l,r比如 3 8找到的结果是
根号8 - 根号3就是2-1=1,其实你是从2.多和1.多来的
假如是 8 , 4 答案就是 2 - 2 =0!!!问题来了
完全平方数在l时会被吃掉,所以要加1,因为在练二分,所以就用二分写

#include <bits/stdc++.h>
using namespace std;
typedef unsigned long long ULL;
int n, a[31633];
const ULL N = 1e9 + 10;
int main()
{
    cin>>n;
    for(ULL i = 0;i < 31633; i++)
    {
        a[i] = i;
    }
    while(n--)
    {
        int l,r,ls,rs;
        cin>>l>>r;
        int i = 0,j = 31622;
        while(i<j)
        {
            int mid = i + j >>1;
            if(mid>sqrt(l))j = mid;
            else i = mid + 1;
        }
        ls = i - 1;
        i = 0,j = 31633;
        while(i<j)
        {
            int mid = i + j >>1;
            if(mid>sqrt(r))j = mid;
            else i = mid + 1;
        }
        rs = i - 1;
        if(ls * ls == l)rs++;
        cout<<rs - ls<<endl;
    }
    return 0;
}

新年 快乐

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值