十五届蓝桥杯国赛模拟(下)

题单详情 - 蓝桥云课 (lanqiao.cn)

填空题:

2360 互质

互质的定义是:两个数最大公约数为1,因此此题利用gcd模板即可AC:

#include<iostream>
using namespace std;
int ans;
int gcd(int a,int b){
    return b?gcd(b,a%b):a;
}
int main(){
    for(int i=1;i<=2020;i++) if(gcd(i,1018)==1) ans++;
    cout<<ans<<endl;
    return 0;
}

17121 混乘数字

下列代码肯定是超时的,但是此题为填空题,考试时先利用dev算出答案,最后直接输出结果即可:

#include<iostream>
#include<cstring>
using namespace std;
long long ans,flag[10],cnt[10];
bool check(long long x){
    memset(cnt,0,sizeof cnt);
    long long xx=x;
    while(xx>0){
        cnt[xx%10]++;
        xx/=10;
    }
    for(long long i=1;i*i<=x;i++){
        long long j=x/i;
        if(i*j==x){
            memset(flag,0,sizeof flag);
            long long ii=i,jj=j;
            int key=0;
            while(ii>0){
                flag[ii%10]++;
                ii/=10;
            }
            while(jj>0){
                flag[jj%10]++;
                jj/=10;
            }
            for(int k=0;k<=9;k++){
                if(flag[k]!=cnt[k]){
                    key=1;
                    break;
                }
            }
            if(key==0) return true;
        }
    }
    return false;
}
int main(){
    //for(int i=1;i<=1000000;i++) if(check(i)) ans++;
    //cout<<ans<<endl;
    cout<<590<<endl;
    return 0;
}

17133 逆元

费马小定理:
如果p是一个质数,而整数a不是p的倍数,则有a^(p-1) ≡ 1(mod p)
即 a^(p-1) = p*k+1 ,即 a*a^(p-2) =p*k+1

乘法逆元的定义 :
如果 (a*x) mod p=1 ,即 a*x=p*k+1 ,则称x为a的模p的乘法逆元
乘法逆元的结论 :
a存在乘法逆元的充要条件是a与p互质,当p为质数时, a^p−2即为a的乘法逆元

fast_power  AC: 

#include<iostream>
using namespace std;
typedef long long ll;
const int p=2146516019;
int temp,ans;
int fast_power(int a,int b,int p){
    int res=1;
    while(b){
        if(b&1) res=(ll)res*a%p;
        b>>=1;
        a=(ll)a*a%p;
    }
    return res;
}
int main(){
    /*
    for(int i=1;i<=233333333;i++){
        temp=fast_power(i,p-2,p);
        ans^=temp;
    }
    cout<<ans<<endl;
    */
    cout<<1307261675<<endl;
    return 0;
}

编程题:

18427 翻转

动态规划 AC:

#include<iostream>
#include<cstring>
using namespace std;
const int N=1e5+10;
char a[N][2];
int n,dp[N][2];
//dp[i][0]:前i个串拼在一起组成的min长度(第i个没有翻转)
//dp[i][1]:前i个串拼在一起组成的min长度(第i个有翻转)
int main(){
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    //初始化dp数组
    memset(dp,0x3f,sizeof dp);
    dp[1][0]=dp[1][1]=2;
    //动态规划
    for(int i=2;i<=n;i++){
        dp[i][0]=min(dp[i-1][0]+1+(a[i-1][1]!=a[i][0]),dp[i-1][1]+1+(a[i-1][0]!=a[i][0]));
        dp[i][1]=min(dp[i-1][0]+1+(a[i-1][1]!=a[i][1]),dp[i-1][1]+1+(a[i-1][0]!=a[i][1]));
    }
    cout<<min(dp[n][1],dp[n][0])<<endl;
    return 0;
}

17139 非对称二叉树

树形DP AC:

#include<iostream>
using namespace std;
const int N=40;
typedef long long ll;
ll n,m,ans,dp[N][N];
//dp[i][j]:有i个节点并且高度为j的非对称二叉树数量
int main(){
    cin>>n>>m;
    dp[0][0]=1;
    for(int i=1;i<=n;i++){
        for(int j=0;j<n;j++){
            int k=i-1-j; 
            for(int hj=j;hj>=0;hj--){
                for(int hk=k;hk>=0;hk--){
                    int maxx=max(hj,hk);
                    int minn=min(hj,hk) ;
                    if(maxx>=m*minn) dp[i][maxx+1]+=dp[j][hj]*dp[k][hk];
                }
            }
        }
    }
    for(int i=n;i>=0;i--) ans+=dp[n][i];
    cout<<ans<<endl;
    return 0;
}

6251 游戏

单调队列+双重循环 (未AC 40points):

#include<iostream>
#define int long long
using namespace std;
const int N=1e5+5;
int n,k,a[N],que[N],maxx[N],minn[N];
double ans;
signed main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    int head=0,tail=-1;
    for(int i=1;i<=n;i++){
        while(head<=tail&&que[tail]<a[i]) tail--;
        que[++tail]=a[i];
        if(i-k>=1&&que[head]==a[i-k]) head++;
        if(i>=k) maxx[i]=que[head];
    }
    head=0,tail=-1;
    for(int i=1;i<=n;i++){
        while(head<=tail&&que[tail]>a[i]) tail--;
        que[++tail]=a[i];
        if(i-k>=1&&que[head]==a[i-k]) head++;
        if(i>=k) minn[i]=que[head];
    }
    for(int i=k;i<=n;i++) for(int j=k;j<=n;j++) ans+=maxx[i]-minn[j];
    printf("%.2lf",ans/((n-k+1)*(n-k+1)));
    return 0;
}

优化:

for(int i=k;i<=n;i++) for(int j=k;j<=n;j++) ans+=maxx[i]-minn[j];
printf("%.2lf",ans/((n-k+1)*(n-k+1)));

--->--->--->

for(int i=k;i<=n;i++) ans+=maxx[i];
for(int i=k;i<=n;i++) res+=minn[i];
printf("%.2lf",(ans-res)/(n-k+1));

AC: 

#include<iostream>
#define int long long
using namespace std;
const int N=1e5+5;
int n,k,a[N],que[N],maxx[N],minn[N];
double ans,res;
signed main(){
    cin>>n>>k;
    for(int i=1;i<=n;i++) cin>>a[i];
    int head=0,tail=-1;
    for(int i=1;i<=n;i++){
        while(head<=tail&&que[tail]<a[i]) tail--;
        que[++tail]=a[i];
        if(i-k>=1&&que[head]==a[i-k]) head++;
        if(i>=k) maxx[i]=que[head];
    }
    head=0,tail=-1;
    for(int i=1;i<=n;i++){
        while(head<=tail&&que[tail]>a[i]) tail--;
        que[++tail]=a[i];
        if(i-k>=1&&que[head]==a[i-k]) head++;
        if(i>=k) minn[i]=que[head];
    }
    for(int i=k;i<=n;i++) ans+=maxx[i];
    for(int i=k;i<=n;i++) res+=minn[i];
    printf("%.2lf",(ans-res)/(n-k+1));
    return 0;
}

17152 最大区间

单调栈 AC:

#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int N=3e5+5;
int n,a[N],stackk[N],top,l[N],r[N],ans;
signed main(){
    cin>>n;
    for(int i=1;i<=n;i++) cin>>a[i];
    a[0]=a[n+1]=-1;top=0;stackk[++top]=0;
    for(int i=1;i<=n;i++){
        while(a[stackk[top]]>=a[i])top--;
        l[i]=stackk[top];
        stackk[++top]=i;
    }
    top=0;stackk[++top]=n+1;
    for(int i=n;i;i--){
        while(a[stackk[top]]>=a[i]) top--;
        r[i]=stackk[top];
        stackk[++top]=i;
    }
    for(int i=1;i<=n;i++) ans=max(ans,(r[i]-l[i]-1)*a[i]);
    cout<<ans<<endl;
    return 0;
}

17147 最大阶梯

动态规划 AC:

#include<iostream>
#include<cstring>
#define int long long
using namespace std;
const int N=1e3+5;
int n,h[N][N],dp[N][N],ans;
void init(){
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) dp[i][j]=1;
}
signed main(){
    ios::sync_with_stdio(false);
    cin>>n;
    memset(h,-1,sizeof h);
    for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) cin>>h[i][j];
    //比较左边和上面
    init();
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(h[i][j]==h[i][j-1]&&h[i][j]==h[i-1][j]){
                dp[i][j]=min(dp[i][j-1],dp[i-1][j])+1;
                ans=max(ans,dp[i][j]);
            }
        }
    }
    //比较左边和下面
    init();
    for(int i=n;i>=1;i--){
        for(int j=1;j<=n;j++){
            if(h[i][j]==h[i][j-1]&&h[i][j]==h[i+1][j]){
                dp[i][j]=min(dp[i][j-1],dp[i+1][j])+1;
                ans=max(ans,dp[i][j]);
            }
        }
    }
    //比较右边和上面
    init();
    for(int i=1;i<=n;i++){
        for(int j=n;j>=1;j--){
            if(h[i][j]==h[i][j+1]&&h[i][j]==h[i-1][j]){
                dp[i][j]=min(dp[i][j+1],dp[i-1][j])+1;
                ans=max(ans,dp[i][j]);
            }
        }
    }
    //比较右边和下面
    init();
    for(int i=n;i>=1;i--){
        for(int j=n;j>=1;j--){
            if(h[i][j]==h[i][j+1]&&h[i][j]==h[i+1][j]){
                dp[i][j]=min(dp[i][j+1],dp[i+1][j])+1;
                ans=max(ans,dp[i][j]);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}

17117 火车运输

动态规划背包问题 AC:

#include<iostream>
#define int long long
using namespace std;
const int N=1005;
int n,A,B,w[205],dp[N][N];
signed main(){
    ios::sync_with_stdio(false);
    cin>>n>>A>>B;
    for(int i=1;i<=n;i++) cin>>w[i];
    for(int i=1;i<=n;i++){
        for(int j=A;j>=0;j--){
            for(int k=B;k>=0;k--){
                if(j>=w[i]) dp[j][k]=max(dp[j][k],dp[j-w[i]][k]+w[i]);
                if(k>=w[i]) dp[j][k]=max(dp[j][k],dp[j][k-w[i]]+w[i]);
            }
        }
    }
    cout<<dp[A][B]<<endl;
    return 0;
}
  • 9
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值