• Daliy Algorithm(二分) -- day 54


    Nothing to fear

    those times when you get up early and you work hard; those times when you stay up late and you work hard; those times when don’t feel like working — you’re too tired, you don’t want to push yourself — but you do it anyway. That is actually the dream. That’s the dream. It’s not the destination, it’s the journey. And if you guys can understand that, what you’ll see happen is that you won’t accomplish your dreams, your dreams won’t come true, something greater will. mamba out


    那些你早出晚归付出的刻苦努力,你不想训练,当你觉的太累了但还是要咬牙坚持的时候,那就是在追逐梦想,不要在意终点有什么,要享受路途的过程,或许你不能成就梦想,但一定会有更伟大的事情随之而来。 mamba out~

    2020.4.9


    慢慢来 打好基础

    递增三元组

    二分的解法可以达到(O(nlogn))

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    
    using namespace std;
    typedef long long ll;
    const int N = 100005;
    int A[N] , B[N] , C[N] ;
    int sum[N] , n;
    ll ans;
    void init()
    {
    	cin >> n;
    	for(int i = 0;i < n ;i ++)scanf("%d",&A[i]);
    	for(int i = 0;i < n ;i ++)scanf("%d",&B[i]);
    	for(int i = 0;i < n ;i ++)scanf("%d",&C[i]);
    
    	sort(A , A + n);
    	sort(C , C + n);
    	sort(B , B + n);
    }
    
    
    int main()
    {
    	init();
    	for(int i = 0;i < n ;i ++)
    	{
    		//找到A中第一个大于等于B[i]的元素/最后一个小于等于B[i]的坐标
    		int l = 0 , r = n - 1;
    		while(l < r)
    		{
    			int mid = l + r + 1 >> 1;
    			if(A[mid] < B[i])l = mid;
    			else r = mid - 1;
    		}
    		int t = 0;
    		if(A[l] >= B[i])l = -1;
    		t = l;
    		l = 0, r = n - 1;
    		while(l < r)
    		{
    			int mid = l + r >> 1;
    			if(C[mid] > B[i])r = mid;
    			else l = mid + 1;
    		}
    		if(B[i] >= C[r])r = n;
    		int right = r;
    		ans += (ll)(n - right ) * (t + 1);
    	}
    	cout << ans << endl;
    	return 0;
    }
    

    lg-p1024 一元三次方程求解

    思路: 实数域二分
    但是题目中说了两个根之间差的绝对值大于等于1
    故我们应该在( i , i + 1) 之间搜索答案

    判断划分区间是否存在根只需要判断
    l - mid : f(l) * f(mid) < 0  // 根在左边区间
    mid - r :  f(r) * f(mid) < 0  // 根在右边区间
    由于判断根重复所以 f(l) 和 f(r) 只需要判断一个即可
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstdlib>
    #include <cstring>
    
    using namespace std;
    double a , b , c , d;
    int s = 0 , t1 , t2;
    double f(double x)
    {
    	return a*(x*x*x) + b*x*x + c*x + d; 
    }
    void bs(double l, double r)
    {
    	if(r - l <= 0.001){
    		printf("%.2f ",l);
    		return;
    	}
    	double mid = (l + r) / 2;
    	double ansl , ansr;
    	ansl = f(l) * f(mid);
    	ansr = f(r) * f(mid);
    	if(f(mid) == 0)printf("%.2f ",mid);
    	if(f(r) == 0)printf("%.2f ",r);
    	if(ansl < 0)bs(l , mid);
    	else if(ansr < 0)bs( mid , r);
    }
    int main()
    {
    	cin >> a >> b >> c >> d;
    	for(int i = -100 ;i <= 99 ;i ++)
    	{
    		if(f(i) * f(i + 1.0) <= 0)
    			bs(i , i + 1.0);
    	}
    	return 0;
    }
    

    lg-p1182数列分段

    思路: 二分 + 贪心
    本体的目标是寻找最大值中的最小值:
    1.采用二分的思路一定要答案是一个单调序列
    2.由于是最大值中的最小值所以左边的边界一定是数组当中组大的哪一个当作独立分组r=所有和

    3. check() 条件采用贪心的思路 : 
    如果当前分组满足二分的当前答案就持续分
    如果拿到下一个数不满足当前二分的最大值就划分
    最后判断分组的个数是否合法 如果合法就让 r = mid
    否则 l = mid + 1
    
    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    #include <cstring>
    #include <cstdlib>
    
    using namespace std;
    const int N = 1000005;
    int n , m , l , r;
    int a[N];
    bool check(int x)
    {
    	int sum = 0 , cnt = 0;
    	for(int i = 1;i <= n ;i ++)
    	{
    		if(sum + a[i] <= x)sum += a[i];
    		else sum = a[i],cnt++;
    	}
    	return cnt + 1 <= m;
    }
    
    int main()
    {
    	int x = 0;
    	cin >> n >> m;
    	for(int i = 1;i <= n ;i ++)
    	{
    		scanf("%d",&a[i]);
    		r += a[i];l = max(l , a[i]);
    	}
    	//确保答案一定在这个区间
    	while(l < r)
    	{
    		int mid = l + r >> 1;
    		if(check(mid))r = mid;
    		else l = mid + 1;
    	}
    	cout << l << endl;
    	return 0;
    }
    
  • 相关阅读:
    php.ini中设置session过期时间
    IP(Internet Protocal) 地址 说明
    html年月日下拉联动菜单 年月日三下拉框联动
    使用数组的键值,做为变量名的方法
    html中js只允许输入数字
    阿里云服务器问题攻略
    小帆远行
    Android图片转换类 1. Bitmap去色,转换为黑白的灰度图, 2. Bitmap图片加圆角效果
    EditText禁止输入回车
    Android之系统自带的文字外观设置
  • 原文地址:https://www.cnblogs.com/wlw-x/p/12670250.html
Copyright © 2020-2023  润新知