算法竞赛进阶指南学习day6

CH1101

题目概述:求1-n所有出栈顺序

思路:深搜

#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int n;int top=0;int in[50],out[50];int cnt=0,chu=0; 
void dfs(int x){//x在这里指当前要入栈的是谁 
	if(cnt==20) return;
	if(chu==n){
		for(int i=1;i<=n;i++){
			cout<<out[i];
		}
		cout<<endl;
		cnt++;
		return ;
	}
	if(top>0){
		int z=in[top];
		top--;//出栈
		chu++;
		out[chu]=z;
		dfs(x);
		top++;
		in[top]=z;
		chu--;
	}
	if(x<=n){
		top++;
		in[top]=x;
		dfs(x+1);
		top--;
	}
}
int main(){
	cin>>n;
	dfs(1);
	return 0;
}


P1031【NOIP2002提高组】不是书里的

打疫苗排队的时候无聊,在手机上打个水题 竟然出在提高组

#include <iostream>
using namespace std;
int a[200],q[200];
int main(){
	int n;
	cin>>n;
	int sum=0;
	for(int i=0;i<n;i++){
		cin>>a[i];
		sum+=a[i];
		}
	int z=sum/n;
	int ans=0;
	for(int i=0;i<n;i++){
		q[i]+=a[i]-z;
		if(q[i]!=0){
			q[i+1]+=q[i];
			ans++;
		}
	}
	cout<<ans;
}

ch1102

题目:和第一个一样但求的是答案个数

思路:因为数据范围到6万,而题一的算法是指数级的,根本不能用,所以就发现了很妙的卡特兰数,具体介绍在https://www.cnblogs.com/wutongtong3117/p/7673100.html,总之最后算一个高精的科特兰数就好了

算卡特兰数的方法:https://www.luogu.com.cn/blog/qiianr-lulala/ka-te-lan-shuo-di-er-san-shi这里将的很清楚了

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
long long n,ans[1200000],l=1,p[1200000],c[1200000],num;
bool vis[1200000];
void cheng(int x) {
	for(int i=1;i<=l;i++) ans[i]*=x;
	l+=6;
	for(int i=1;i<=l;i++) {
		ans[i+1]+=ans[i]/10;
		ans[i]%=10;
	}
	while(!ans[l]) l--;
}
int main() {
	cin>>n;
	ans[1]=1;
	for(int i=2;i<=n*2;i++) if(!vis[i]) {//埃筛找质数 
		p[++num]=i;
		for(int j=i;j<=120000;j+=i) vis[j]=1;
	}
	for(int i=1;i<=num;i++) {
		long long z=p[i];
		while(z<=n*2) {
			c[i]+=n*2/z-n/z-(n+1)/z;
			z*=p[i];
		}
		while(c[i]--) {
			cheng(p[i]);
		}
	}
	for(int i=l;i>=1;i--) {
		cout<<ans[i];
	}
	return 0;
}

CH1201最大子序和

思路:前缀和用于求区间值,固定右端,左端找到最值即可

#include<iostream>
#include<cstdio>
#include<cmath>
#include<vector>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int n;int m;
int a[1000000];
int sum[1000000];
int x;
int ans;
int main()
 {
    scanf("%d%d",&n,&m);
    int l=1;int r=1;
    for(int i=1;i<=n;i++)
     {
        while(l<=r&&a[l]<i-m)l++;
        cin>>x;
        sum[i]=sum[i-1]+x;
        ans=max(ans,sum[i]-sum[a[l]]);
        while(l<=r&&sum[a[r]]>=sum[i])r--;
        a[++r]=i;
     }
    cout<<ans;
 }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值