蓝桥杯水题合集

注:此博客记录一些蓝桥杯水题,但是自己第一时间没想出来,但暴力的题目

蓝桥杯2015初赛牌型种数题目链接

题目思路

我本以为是组合数学,但是发现组合数学好像写不出,去看了一下答案居然是13重for或暴力dfs,不过dp也可以求解

dfs

#include<cstdio>
#include<cmath>
#include<cstring>
using namespace std;
typedef long long ll;
int ans;
void dfs(int cnt,int k){
    if(cnt==13){
        ans++;
    }
    if(cnt>=13||k>=13){
        return ;
    }
    for(int i=0;i<=4;i++){
        dfs(cnt+i,k+1);
    }
}
int main(){
    dfs(0,0);
    printf("%d\n",ans);
    return 0;
}

dp

#include <iostream>
#include <cstdio>
using namespace std;
typedef long long LL;

LL dp[14][14]; // dp[i][j]: 当前到第i张牌,总共有j张牌时的解的个数

int main() {
    dp[1][0] = dp[1][1] = dp[1][2] = dp[1][3] = dp[1][4] = 1;

    for (int i = 2; i <= 13; i++) {
        for (int k = 0; k <= 13; k++) {
            if (k - 4 >= 0) dp[i][k] += dp[i-1][k-4];
            if (k - 3 >= 0) dp[i][k] += dp[i-1][k-3];
            if (k - 2 >= 0) dp[i][k] += dp[i-1][k-2];
            if (k - 1 >= 0) dp[i][k] += dp[i-1][k-1];
            dp[i][k] += dp[i-1][k];
        }
    }

    cout << dp[13][13] << endl;
    return 0;
}

蓝桥杯2015初赛生命之树题目链接

题目思路

本来以为是树的直径模板题,发现不是,因为这个是可以分叉的链,而树的直径是要求一条不能分叉的链。但其实这样更加简单,要分类讨论一下,自己原先没有分类讨论就wa了,树形dp一下就行了

代码

#include<cstdio>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=1e5+5;
typedef long long ll;
int n,u,v,a[maxn],head[maxn],cnt;
ll dp[2][maxn];
struct node{
    int to,next;
}e[maxn<<1];
void add(int u,int v){
    e[++cnt].to=v;
    e[cnt].next=head[u];
    head[u]=cnt;
}
void dfs(int son,int fa){
    dp[1][son]=a[son];//选
    dp[0][son]=0;//不选
    for(int i=head[son];i;i=e[i].next){
        if(e[i].to!=fa){
            dfs(e[i].to,son);
            dp[1][son]=max(dp[1][son],dp[1][son]+dp[1][e[i].to]);
            dp[0][son]=max(dp[0][son],dp[1][e[i].to]);
        }
    }
}
int main(){
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        scanf("%d",&a[i]);
    }
    for(int i=1;i<=n-1;i++){
        scanf("%d %d",&u,&v);
        add(u,v),add(v,u);
    }
    dfs(1,1);
    ll ans=-0x3f3f3f3f3f3f3f3f;
    for(int i=1;i<=n;i++){
        ans=max(ans,dp[0][i]);
        ans=max(ans,dp[1][i]);
    }
    printf("%lld\n",ans);
    return 0;
}

蓝桥杯2015决赛四阶幻方题目链接

题目思路

我本来以为是全排列函数,后面发现跑不出15!的阶乘根本跑不出,后面发现是减无数次枝,就算枝减的少一点也没事,等他跑出来直接打表就行

代码

#include<cstdio>
using namespace std;
int a[20],b[20],ans;
void dfs(int step){
    if(step==5){
        if(a[1]+a[2]+a[3]+a[4]!=34){//第一行
             return ;
        }
    }else if(step==9){
        if(a[5]+a[6]+a[7]+a[8]!=34){//第二行
            return ;
        }
    }else if(step==11){//主对角线
        int sum=a[4]+a[7]+a[10];
        if((34-sum>=2&&b[34-sum]!=0)||(34-sum<2)){
            return ;
        }
    }else if(step==12){
        int sum=a[1]+a[6]+a[11];
        if((34-sum>=2&&b[34-sum]!=0)||(34-sum<2)){
            return ;
        }
    }else if(step==13){//第三行
        if(a[9]+a[10]+a[11]+a[12]!=34){
            return ;
        }
    }else if(step==14){//第一列
        if(a[1]+a[5]+a[9]+a[13]!=34){
            return ;
        }
        if(a[4]+a[7]+a[10]+a[13]!=34){//次对角线
            return ;
        }
    }else if(step==15){//第二列
        if(a[2]+a[6]+a[10]+a[14]!=34){
            return ;
        }
    }else if(step==16){//第三列
        if(a[3]+a[7]+a[11]+a[15]!=34){
            return ;
        }
    }else if(step==17){
        if(a[13]+a[14]+a[15]+a[16]!=34){//第四行
             return ;
        }
        if(a[4]+a[8]+a[12]+a[16]!=34){//第四列
            return ;
        }
        if(a[1]+a[6]+a[11]+a[16]!=34){//主对角线
            return ;
        }
        ans++;
        return ;
    }
    for(int i=2;i<=16;i++){
        if(!b[i]){
            a[step]=i;
            b[i]=1;
            dfs(step+1);
            b[i]=0;
        }
    }
}
int main(){
    a[1]=1,b[1]=1;//初始化
    dfs(2);
    printf("%d\n",ans);
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值