2021-08-062022蓝桥杯暑假练习赛4

**

2022蓝桥杯暑假练习赛4

**

注:模板题场

1、试题 算法提高 数的划分
在这里插入图片描述
求完全背包的方案数模板题

#include<bits/stdc++.h>
using namespace std;
int n;
int dp[105];
int main(){
    cin>>n;
    dp[0]=1;
    for(int i=1;i<=n;i++){
        for(int j=i;j<=n;j++){
            dp[j]+=dp[j-i];
        }
    }
    cout<<dp[n]<<"\n";
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

2、试题 算法提高 题目 2 密码锁
在这里插入图片描述
解题思路:bfs变式,很像之前练习题的迷宫问题(CSL的校园卡),存好每种字符串和到达该字符串的最小步数,然后直接bfs,数据小无需剪枝。

#include<bits/stdc++.h>
using namespace std;
int n,n0,n1,n2;
string s;
struct node{
    string s;
    int step;
};
queue<node>q;
map<string,bool>mp;
void bfs(){
    q.push({s,0});
    mp[s]=1;
    while(!q.empty()){
        node t=q.front(); q.pop();
        mp[t.s]=1;
        if(t.s.find("2012")!=-1){printf("%d\n",t.step);return;}
        else{
            string ss=t.s;
            for(int i=1;i<n;i++){
                swap(ss[i],ss[i-1]);
                if(!mp[ss]) q.push({ss,t.step+1});
                swap(ss[i],ss[i-1]);
            }
        }
    }
}

int main(){
    cin>>n>>s;
    for(int i=0;i<s.length();i++){
        if(s[i]=='0') n0++;
        if(s[i]=='1') n1++;
        if(s[i]=='2') n2++;
    }
    if(!n0||!n1||n2<2) puts("-1");
    else bfs();
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

3、试题 算法训练 结点选择
在这里插入图片描述
树形dp模板题
解题思路:
1、设计dp数组的状态dp[当前节点][不选(0)/选(1)]。
2、状态考虑:①当前节点不选,那么跟他相邻的节点有可选可不选两种情况,取两者最大值
②当前节点选,那么只有一种情况,就是跟他相邻的节点都不选

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
int n;
int dp[N][2];
int to[N*2],nex[N*2],fir[N*2],idx;

void add(int u,int v){
    to[++idx]=v;
    nex[idx]=fir[u];
    fir[u]=idx;
}

void dfs(int u,int fa){
    for(int i=fir[u];~i;i=nex[i]){
        int v=to[i];
        if(v!=fa){
            dfs(v,u);
            dp[u][1]+=dp[v][0];
            dp[u][0]+=max(dp[v][1],dp[v][0]);
        }
    }
}

int main(){
    memset(fir,-1,sizeof(fir));
    scanf("%d",&n);
    for(int i=1;i<=n;i++) scanf("%d",&dp[i][1]);
    for(int i=1;i<n;i++){
        int u,v; scanf("%d%d",&u,&v);
        add(u,v),add(v,u);
    }
    dfs(1,0);
    cout<<max(dp[1][0],dp[1][1])<<"\n";
    return 0;
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

4、试题 算法提高 分苹果
在这里插入图片描述
线段树模板题:区间修改+单点查询
注:应该还有更简单的做法,但直接上模板就行了。

#include<bits/stdc++.h>
using namespace std;
const int N=1e5+5;
struct node{
    int l,r,sum,add;
}tr[N*4];
int n,m;

void pushdown(int u){
	node &res=tr[u],&left=tr[u<<1],&right=tr[u<<1|1];
	if(res.add){
		left.add+=res.add,left.sum+=(left.r-left.l+1)*res.add;
		right.add+=res.add,right.sum+=(right.r-right.l+1)*res.add;
		res.add=0;
	}
}

void pushup(int u){tr[u].sum=tr[u<<1].sum+tr[u<<1|1].sum;}

void build(int u,int l,int r){
    if(l==r){tr[u]={l,r,0,0};}
    else{
        tr[u]={l,r};
        int mid=l+r>>1;
        build(u<<1,l,mid),build(u<<1|1,mid+1,r);
        pushup(u);
    }
}

int query(int u,int l,int r,int x){
    if(tr[u].l==x&&tr[u].r==x) return tr[u].sum;
    pushdown(u);
    int mid=tr[u].l+tr[u].r>>1;
    if(mid>=x) return query(u<<1,l,mid,x);
    if(mid<x) return query(u<<1|1,mid+1,r,x);
}

void modify(int u,int l,int r,int d){
	if(tr[u].l>=l&&tr[u].r<=r){
		tr[u].sum+=1ll*(tr[u].r-tr[u].l+1)*d;
		tr[u].add+=d; 
	}
	else{
		pushdown(u);
		int mid=tr[u].l+tr[u].r>>1;
		if(l<=mid) modify(u<<1,l,r,d);
		if(r>mid) modify(u<<1|1,l,r,d);
		pushup(u);
	}
}


int main(){
    scanf("%d%d",&n,&m);
    build(1,1,n);
    while(m--){
        int l,r,c; scanf("%d%d%d",&l,&r,&c);
        modify(1,l,r,c);
    }
    for(int i=1;i<=n;i++) printf("%d ",query(1,1,n,i));
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

5、试题 算法提高 素数求和
在这里插入图片描述
mou筛模板题

#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e6;
int prime[N+5],cnt;
bool vis[N+5];
int n,sum;

void build(){
    for(int i=2;i<=N;i++){
        if(!vis[i]) prime[cnt++]=i;
        for(int j=0;prime[j]<=N/i;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0) break;
        }
    }
}

signed main(){
    build();
    cin>>n;
    for(int i=0;i<cnt;i++){
        if(prime[i]<=n) sum+=prime[i];
        else break;
    }
    cout<<sum<<"\n";
}

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

6、试题 算法提高 林丹大战李宗伟
在这里插入图片描述
根据题意模拟

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int x=0,y=0;
	int n;
	while(cin>>n)
	{
		if(n==0) x++;
		if(n==1) y++;
		if(x>=21&&x-y>1)
		{
			cout<<"0";	
			break;
		}
		else if(y>=21&&y-x>1)
		{
			cout<<"1";
			break;
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值