蓝桥杯2021年A组国赛

纯质数

题目大意:

image-20230608205455013

题解:

就是线性筛的运用罢了

Code:
#include <bits/stdc++.h>
using namespace std;
#define ioss ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
typedef long long ll;
const int MAXN=20210605;
int pr[MAXN+10];
bool bj[MAXN+10];
void Prime(){
    for(int i=2;i<=MAXN;++i){
        if(!bj[i]){
            pr[++pr[0]]=i;
        }
        for(int j=1;j<=pr[0]&&i*pr[j]<=MAXN;++j){
            bj[i*pr[j]]=1;
            if(i%pr[j]==0)break;
        }
    }
}
bool y[12];
bool yes(int x){
    while(x){
        if(!y[x%10])return 0;
        x/=10;
    }
    return 1;
}
int main(){
    Prime();
    y[2]=y[3]=y[5]=y[7]=1;
    int cnt=0;
    for(int i=1;i<=pr[0];++i){
        if(yes(pr[i]))cnt++;
    }
    cout<<cnt; //1903
    return 0;
}

完全日期

题目大意:

image-20230609082622593

题解:

模拟

Code:
#include <bits/stdc++.h>
using namespace std;
#define ioss ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
typedef long long ll;
int ans;
void calc(int y,int m,int d){
    int t=0;
    while(y){
        t+=y%10;
        y/=10;
    }
    while(m){
        t+=m%10;
        m/=10;
    }
    while(d){
        t+=d%10;
        d/=10;
    }
    int st=sqrt(t);
    if(st*st==t)ans++;
}
int calcmd(int y,int m){
    if(m==1||m==3||m==5||m==7||m==8||m==10||m==12) return 31;
    if(m==2){
        if(y%100==0&&y%400==0||y%100!=0&&y%4==0) return 29;
        else return 28;
    }
    else return 30;
}
int main(){
    int y=2001,m=1,d=1,md=31;
    while(1){
        calc(y,m,d);
        if(y==2021&&m==12&&d==31)break;
        ++d;
        if(d>md){
            ++m;
            md=calcmd(y,m);
            d=1;
            if(m>12){
                ++y;
                m=1;
                md=31;
            }
        }
    }
    cout<<ans; //977
    return 0;
}

最小权值

题目大意:

image-20230609083610919

题解:

记忆化搜索

以节点数为状态,状态量其实特别少,只有2021个

所以直接采用记忆化搜索

Code:
#include <bits/stdc++.h>
using namespace std;
#define ioss ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
typedef long long ll;
ll f[2050];
inline ll Min(ll x,ll y){
    return (x<y?x:y);
}
ll W(ll num){
    if(num==0)return 0;
    if(f[num])return f[num];
    ll tmp=9e18;
    for(ll L=0;L<=num-1;++L){
        ll R=num-L-1;
        tmp=Min(tmp,1+2*W(L)+3*W(R)+L*L*R);
    }
    return f[num]=tmp;
}
int main(){
    cout<<W(2021); //2653631372
    return 0;
}

⭐️覆盖

题目大意:

image-20230609085232882

题解:

这个题比较有意思,值得复习

状态压缩DP

状态和状态转移方式见代码备注

Code:
#include <bits/stdc++.h>
using namespace std;
#define ioss ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
typedef long long ll;
int f[10][300]; //f[i][j]表示把第i-1层填满,并且第i层的状态为j的覆盖方案数
void dfs(int i,int sta,int now,int exsta){ //now即以前已经填完
    if(now==7){
        f[i+1][exsta]+=f[i][sta];
        return;
    }
    if(now==8)return;
    if((sta>>(now+1))&1){
        dfs(i,sta,now+1,exsta);
    }else{
        //shu
        dfs(i,sta,now+1,exsta|(1<<now+1));
        //heng
        if(!((sta>>(now+2))&1))
            dfs(i,sta,now+2,exsta);
    }
}
int main(){
    f[0][0]=1;
    dfs(0,0,-1,0); //用f[0][0]去拓展f[1][sta]
    for(int i=1;i<=7;++i){
        for(int j=0;j<=255;++j){
            if(!f[i][j])continue;
            dfs(i,j,-1,0);
        }
    }
    cout<<f[8][0]; //12988816
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值