2021算法竞赛入门班第二节课递归分治二分练习题

Posted 辉小歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021算法竞赛入门班第二节课递归分治二分练习题相关的知识,希望对你有一定的参考价值。

华华给月月准备礼物【二分】


https://ac.nowcoder.com/acm/problem/23049
就是一个常见的二分模板

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL a[N],n,k;
bool check(int x)

	int cnt=0;
	for(int i=0;i<n;i++) cnt+=a[i]/x;
	if(cnt>=k) return true;
	return false;

int main(void)

	cin>>n>>k;
	for(int i=0;i<n;i++) cin>>a[i];
	LL l=0,r=1e9+10;
	while(l<r)
	
		LL mid=l+r+1>>1;
		if(check(mid)) l=mid;
		else r=mid-1;
	
	cout<<l;
	return 0;

The Biggest Water Problem【模拟】


https://ac.nowcoder.com/acm/problem/15173

#include<bits/stdc++.h>
using namespace std;
int main(void)

	int n; cin>>n;
	while(n>=10)
	
		int sum=0;
		while(n) sum+=n%10,n/=10;
		n=sum;
	
	cout<<n;
	return 0;

Bits【递归模拟 / 未完成】


https://ac.nowcoder.com/acm/problem/201605


[NOIP2004]FBI树【树的后序遍历】


https://ac.nowcoder.com/acm/problem/16660

#include<bits/stdc++.h>
using namespace std;
int n;
string s;
void dfs(string s)

    if(s.size()>1)
    
        dfs(s.substr(0,s.size()/2));
        dfs(s.substr(s.size()/2));
    
    int cnt0=0,cnt1=0;
    for(int i=0;i<s.size();i++) 
        if(s[i]=='0') cnt0++;
        else cnt1++;
    if(cnt0&&cnt1) cout<<'F';
    else if(cnt0&&!cnt1) cout<<'B';
    else cout<<'I';

int main(void)

    cin>>n>>s;
    dfs(s);
    return 0;

[USACO 2009 Dec S]Music Notes【二分+前缀和】


https://ac.nowcoder.com/acm/problem/24866

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+10;
int a[N],n,m;
int main(void)

	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i],a[i]+=a[i-1];
	while(m--)
	
		int x; cin>>x;
		int l=1,r=n;
		while(l<r)
		
			int mid=l+r>>1;
			if(a[mid]>=(x+1)) r=mid;
			else l=mid+1;
		
		cout<<l<<endl;
	

[NOIP2009]分数线划定【模拟】


https://ac.nowcoder.com/acm/problem/16625

#include<cstdio>
#include<algorithm>
using namespace std;
struct student

    int sum;//分数
    int id;//学号
s[5005];
bool cmp(student a,student b)

    if(a.sum!=b.sum)
        return a.sum>b.sum;
    else
        return a.id<b.id;
     

int main(void)

    int n,m;//n代表总的人数 m代表志愿者人数
    int end_number;//进入面试的人数
    int end_score;//面试分数线
    int i;
    scanf("%d %d",&n,&m);
    end_number=m*1.5;
    for(i=0;i<n;i++)
    
        scanf("%d %d",&s[i].id,&s[i].sum);
    
    sort(s,s+n,cmp);//总的排序
    end_score=s[end_number-1].sum;//面试的分数线
    for(i=end_number;i<n;i++)//加上重分的人
    
        if(s[i].sum==end_score)
            end_number++;
        else
            break;
    
    printf("%d %d\\n",end_score,end_number);
    for(i=0;i<end_number;i++)
    
        printf("%d %d\\n",s[i].id,s[i].sum);
    
    return 0;

逆序数【归并排序】


https://ac.nowcoder.com/acm/problem/15163

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int N=1e5+10;
LL a[N],b[N],n,res;
void merge_sort(int l,int r)

	if(l>=r) return;
	int i=l,mid=l+r>>1,j=mid+1;
	merge_sort(l,mid),merge_sort(mid+1,r);
	int k=0;
	while(i<=mid&&j<=r) 
	
		if(a[i]<=a[j]) b[k++]=a[i++];
		else
		
			res+=mid-i+1;
			b[k++]=a[j++];
		
	
	while(i<=mid) b[k++]=a[i++];
	while(j<=r) b[k++]=a[j++];
	for(int i=l,j=0;i<=r;i++,j++) a[i]=b[j];

int main(void)

	cin>>n;
	for(int i=0;i<n;i++) cin>>a[i];
	merge_sort(0,n-1);
	cout<<res;
	return 0;

逆序对【组合数 / 推式子】


https://ac.nowcoder.com/acm/problem/14731

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
const int mod=1e9+7;
LL quick_mi(LL a,LL b, LL p)

	LL sum=1;
	while(b)
	
		if(b&1) sum=sum*a%p; 
		b>>=1;
		a=(a*a)%p;
	
	return sum%p;

int main(void)

	LL n; cin>>n;
	if(n==1) cout<<0;
	else if(n==2) cout<<1;
	else cout<<(n%mod)*((n-1)%mod)%mod*quick_mi(2,n-3,mod)%mod;
	return 0;

完全平方数【二分】


https://ac.nowcoder.com/acm/problem/14733

#include<bits/stdc++.h>
using namespace std;
typedef long long int LL;
vector<LL>ve;
int main(void)

	for(LL i=0;i<=1e5;i++) ve.push_back(i*i);
	int n; cin>>n;
	while(n--)
	
		LL a,b,l,r; cin>>a>>b;
		int len1=0,len2=0;
		l=0,r=ve.size()-1;
		while(l<r)
		
			int mid=l+r>>1;
			if(ve[mid]>=a) r=mid;
			else l=mid+1;
		
		len1=l;
		l=0,r=ve.size()-1;
		while(l<r)
		
			int mid=l+r+1>>1;
			if(ve[mid]<=b) l=mid;
			else r=mid-1;
		
		len2=l;
		cout<<len2-len1+1<<endl;
	
	return 0;

以上是关于2021算法竞赛入门班第二节课递归分治二分练习题的主要内容,如果未能解决你的问题,请参考以下文章

2021算法竞赛入门班第七节课图论练习题

2021算法竞赛入门班第九节课线段树练习题

2021算法竞赛入门班第八节课数学习题

2021算法竞赛入门班第十节课字符串练习题

2021算法竞赛入门班第一节课枚举贪心习题

2021算法竞赛入门班第三节课堆栈队列并查集等习题