分治练习

渣渣2week写完……

区间合并

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <string>
#include <cstdlib>
#include <cmath>

using namespace std;
struct qu{
int l;
int r;
}n[500000];
bool cmp(qu s,qu t)
{
return s.l<t.l;
}
int main()
{
int k,p;
cin>>k;
for (int i=0;i!=k;++i)
scanf("%d %d",&n[i].l,&n[i].r);
//这其实是贪心题吧?区间覆盖问题的写法
sort(n,n+k,cmp);
for (int i=0;i!=k-1;++i)
{
if (n[i].r<n[i+1].l)
{
cout<<"no";
return 0;
}
n[i+1].r=n[i].r<n[i+1].r?n[i+1].r:n[i].r;
n[i+1].l=n[i].l>n[i+1].l?n[i+1].l:n[i].l;
}
cout<<n[k-1].l<<' '<<n[k-1].r;
return 0;
}

月度开销

#include <iostream>
#include <cstdio>
using namespace std;

int money[100005];
int n,m,l=1000000,r=0,mid;

//神奇的二分方法……
bool check(int num){
	int sum = 1;
	int t=num;
	for(int i=1;i<=n;++i){
		if(t>=money[i])
			t-=money[i];
		else if(money[i]>num)//注意!!
		    return false;
		else
			++sum,t =num - money[i];
	}
	return sum <= m;
}

/*bool check2(int num){
	int sum = 0;
	int t=0;
	for(int i=1;i<=n;++i){
		t += money[i];
		
		if(t>num){
			++sum;
			t = money[i];
		}
	}
	++sum;
	return sum <= m;
}*/

int main(){
	
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;++i){
	    scanf("%d",&money[i]);
	    r += money[i];
    }
    l=0;
    while(l<r){
    	mid = (l+r)/2;
    	if(check(mid))
    	   r=mid;
    	else
    	   l =mid+1;
	}
	//cout<<l<<" "<<r<<endl;
	//if(check(r)) l=r; 
	printf("%d",l);
	return 0;
}

和为给定数

//折半搜索
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;

long long a[100005];

int main(){
	long long m,t,r,l,mid;
	long long ans1,ans2;
	int n;
	scanf("%d",&n);
	for(int i=1;i<=n;++i)
	    scanf("%lld",&a[i]);
	scanf("%lld",&m);
	sort(a+1,a+1+n);
	for(int i=1;i<=n;++i){
		t = m - a[i];//折半搜索
		l = i+1;     //注意不能把a[i]纳入搜索范围
		r = n;
		while(l<r){
			mid = (r+l)/2;
			if(a[mid]>=t)
			    r=mid;
			else
			    l=mid+1;    
		}
		if(a[l] == t){
				printf("%lld %lld",a[i],t);
				return 0;
		}
	}
	printf("No");
	return 0;
} 

膨胀的木棍

//没做出来,数学不好……
// cmath 反三角函数(知道三角函数值求弧度制下的角) asin()
#include<cstdio>
#include<cstdlib>
#include<cmath>
int main()
{
    double l, ll, rig, lef, mid, n, c;
    scanf("%lf%lf%lf", &l, &n, &c);
    //注意此处
    if(l<1e-14)
    {
        printf("0.000\n");
        return 0;
    }
    ll=l*(1+n*c);
    lef=0.0;          //角的极小值
    rig=asin(1.0);    //角的极大值
    //由于三角函数转换,得到 h= (l/2)*tan(@/2) , 所以h只与角@有关,使用二分逼近法去求解最接近的@即可
    //注意,二分验证是让 ll与角@ 计算得到的 木棍原始长度l`=ll*sin@/@ 与 l 进行比较,且l`与@成反比例关系
    while(rig-lef>1e-14)   //在极大值与极小值之间进行二分,这个地方精度控制太低就过不了了。精度要求很高。
    {
        mid=(rig+lef)/2;
        if(ll*sin(mid)/mid<=l)
            rig=mid;
        else
            lef=mid;
    }
    printf("%.3lf\n", l/2*tan(lef/2));
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值