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;
}