备战蓝桥

0地宫取宝 - 蓝桥云课 (lanqiao.cn)

对于该问题,首先是个迷宫问题,于是先考虑暴力求解,对于暴力来说,有这样一种方法: 对于任何一点来说,都可以进行选或者不选,然后当走到终点时如果符合条件则答案加 $1$,这样做的时间复杂度是 $2^n 也就是 2^50$,很明显得不到满分. 既然是迷宫那么可以考虑记忆化搜索,多加入两维数组,分别是当前的最大值和当前选择的数量,那么我们可以在搜索的过程中大大减少时间损耗

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
int mp[100][100],n,m,k;
int dx[]={0,1},dy[]={1,0};
int dp[100][100][15][15];
int dfs(int x,int y,int num,int now){
    if(x>n||y>m) return 0;
    if(dp[x][y][num][now]!=-1) return dp[x][y][num][now];
    int res=0;
    if(x==n&&y==m){
        if(num==k||((num==k-1)&&mp[x][y]>now)) res++;
    }
    else{
        res+=dfs(x+1,y,num,now)%mod+dfs(x,y+1,num,now)%mod;
        if(mp[x][y]>now) res+=dfs(x+1,y,num+1,mp[x][y])%mod+dfs(x,y+1,num+1,mp[x][y])%mod;
    }
    dp[x][y][num][now]=res%mod;
    return dp[x][y][num][now];
}
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) cin>>mp[i][j];
    memset(dp,-1,sizeof dp);
    cout<<dfs(1,1,0,-1);
    return 0;
}

 

0包子凑数 - 蓝桥云课 (lanqiao.cn)

首先考虑什么情况下为 $INF$,很明显如果所有的数之间都能互相整除,也就是说任何一个数都能由另一个数变换而来,这种情况一定会出现无限多,否则考虑有限,由于 $N<100$ 所以考虑枚举,进行背包规划,算出 $100000$ 以内可以被组成的数,输出不可被组成的数目即可,那么为什么这样是正确的呢? 

​在数论中,裴蜀定理是一个关于最大公约数(或最大公约式)的定理。裴蜀定理得名于法国数学家艾蒂安·裴蜀,说明了对任何整数 $a$、$b$ 和它们的最大公约数 $d = \gcd(a, b)$,关于未知数 $x$ 和 $y$ 的线性丢番图方程

$$ax + by = m$$

有解当且仅当 $d | m$。裴蜀等式有解时必然有无穷多个整数解。

特别来说,方程 $ax + by = 1$ 有解当且仅当整数 $a$ 和 $b$ 互素。对于多个整数而言,情况是类似的。

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
bool dp[N];
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n,num,res=0; cin>>n>>num;
    vector<int>a(n+1);
    a[1]=num,dp[0]=1,dp[a[1]]=true;
    for(int i=2;i<=n;i++){
        cin>>a[i];
        num=__gcd(num,a[i]),dp[a[i]]=true;
    }
    if(num>1) return cout<<"INF"<<endl,0;
    for(int i=1;i<=100000;i++)
        for(int j=1;j<=n;j++)
           if(dp[i]) dp[i+a[j]]=true;
    for(int i=1;i<=100000;i++)
        if(!dp[i]) res++;
    cout<<res;
    return 0;
}

0轨道炮 - 蓝桥云课 (lanqiao.cn)

由于数据范围,考虑枚举每一个点,对于每一个点,计算出其它所有点到达这个点所需要的时间,然后进行更新答案即可

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
struct node{
    int x,y,vx,vy;
}p[N];
signed main()
{
    std::ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
    int n,res=0; cin>>n;
    for(int i=1;i<=n;i++){
        int a,b,c; char d; cin>>a>>b>>c>>d;
        if(d=='L'||d=='R') p[i]={a,b,(d=='R'?c:-c),0};
        else p[i]={a,b,0,(d=='U'?c:-c)};
    }
    for(int i=1;i<=n;i++){
        map<int,int>mp;
        int cnt=1;
        for(int j=1;j<=n;j++){
            if(i==j) continue;
            int dx=p[j].x-p[i].x,dv=p[i].vx-p[j].vx;
            if(!dv){
                if(!dx) cnt++;
                res=max(res,cnt); continue;
            }
            int t=dx/dv;
            if(dx%dv||t<0) continue;
            mp[t]++,res=max(res,mp[t]+cnt);
        }
    }
    for(int i=1;i<=n;i++){
        map<int,int>mp;
        int cnt=1;
        for(int j=1;j<=n;j++){
            if(i==j) continue;
            int dy=p[j].y-p[i].y,dv=p[i].vy-p[j].vy;
            if(!dv){
                if(!dy) cnt++;
                res=max(res,cnt); continue;
            }
            int t=dy/dv;
            if(dy%dv||t<0) continue;
            mp[t]++,res=max(res,mp[t]+cnt);
        }
    }
    cout<<res<<endl;
    return 0;
}

0故障 - 蓝桥云课 (lanqiao.cn)

概率论基础

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=1e6+10,mod=1e9+7;
bool vis[N];
struct node{
    int id;
    double w;
    bool operator<(const node&W)const{
        if(w==W.w) return id<W.id;
        return w>W.w;
    }
}p[N];
signed main()
{
    int n,m,q; cin>>n>>m;
    double sum=0;
    vector<double>a(n+1);
    vector<vector<double>>b(n+1,vector<double>(m+1));
    for(int i=1;i<=n;i++) cin>>a[i];
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++) cin>>b[i][j];
    cin>>q;
    while(q--){
        int x; cin>>x;
        vis[x]=true;
    }
    for(int i=1;i<=n;i++){
        double now=a[i];
        for(int j=1;j<=m;j++){
            if(vis[j]) now*=b[i][j];
            else now*=(100-b[i][j]);
        }
        sum+=now,a[i]=now;
    }
    for(int i=1;i<=n;i++) p[i]={i,a[i]/sum*100};
    sort(p+1,p+1+n);
    for(int i=1;i<=n;i++) printf("%d %.2lf\n",p[i].id,p[i].w);
    return 0;
}

 

posted @ 2024-02-27 21:06  o-Sakurajimamai-o  阅读(29)  评论(0)    收藏  举报
-- --