蓝桥杯2021省b题解

  1. 卡片

int p[10];
int main()
{
    for (int e = 0; e < 10; e++)
        p[e] = 2021;
    for (int e = 1; e <= 5000; e++)
        for (int i = e; i != 0; i /= 10)
            if (!p[i % 10])
            {
                cout << e;
                return 0;
            }
            else
                p[i % 10]--;
}
  1. 直线


typedef long long ll;
const int maxn = 100000 + 5;
const int mod = 1e9+7;

int n;
int a[10];
bool work(int x){
    while(x){
        int temp=x%10;
        x/=10;
        if(a[temp]>0){
            a[temp]--;
        }
        else{
            return false;
        }
    }
    return true;
}
int main(){
    while(cin>>n){
        for(int i=0;i<=9;i++)a[i]=n;
        int cnt=1;
        while(true){
            if(work(cnt)){
                cnt++;
            }
            else{
                break;
            }
        }
        cout<<cnt-1<<endl;
    }
    return 0;
}
  1. 货物摆放

int mian()
{
long long a=2021041820210418;
long long p[5000],ans=0,c=0;
for (int e=1;e<=sqrt(a);e++)
{
if (a%e==0)
{
p[++ans]=e;
if (e*e!=a)
p[++ans]=a/e;
}
}
for (int i=1;i<=ans;i++)
for (int j=1;i<=ans;i++)
for (int k=1;i<=ans;i++)
if (p[i]*p[j]*p[k]==a)
c++;
cout<<c;
}
  1. 路径

typedef long long ll;
const int maxn = 10000 + 5;
const int mod = 1e9+7;
const int inf = 0x3f3f3f3f;

//最短路板子题。
int n;
int g[maxn][maxn];
int dist[maxn];
bool vis[maxn];
int gcd(int n,int m){
    return n%m?gcd(m,n%m):m;
}
void init(){
    memset(vis,0,sizeof(vis));
    for(int i=1;i<=n;i++){
        for(int j=1;j<=i;j++){
            if(abs(i-j)<=21){
                g[i][j]=g[j][i]=i*j/gcd(i,j);
            }
            else{
                g[i][j]=g[j][i]=inf;
            }
        }
    }
}
void dijkstra(int st){
    for(int i=1;i<=n;i++){
        dist[i]=g[st][i];
    }
    vis[st]=true;
    for(int i=1;i<=n;i++){
        int minn=inf,index;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&dist[j]<minn){
                minn=dist[j];
                index=j;
            }
        }
        if(minn==inf)break;
        vis[index]=true;
        for(int j=1;j<=n;j++){
            if(!vis[j]&&dist[j]>dist[index]+g[index][j]){
                dist[j]=dist[index]+g[index][j];
            }
        }
    }
    cout<<dist[n]<<endl;//n=2021 print:10266837
}
void solve(){
    init();
    dijkstra(1);
}
int main(){
    while(cin>>n){
        solve();
    }
    return 0;
}
  1. 空间

int main()
{
cout<<67108864;
}
  1. 砝码称重

const int N = 1e5 + 5;
bool k[105][N];
int main()
{
    int n, m, p[110];
    m = 0;
    cin >> n;
    for (int e = 1; e <= n; e++)
    {
        cin >> p[e];
        m += p[e];
    }
    k[0][0] = true;
    for (int i = 1; i <= n; i++)
        for (int j = 0; j <= m; j++)
            k[i][j] = k[i-1][j] || k[i-1][j + p[i]]|| k[i-1][abs(j - p[i])];
    int ans = 0;
    for (int j = 1; j <= m; j++)
        if (k[n][j])
            ans++;
    cout << ans;

}
  1. 括号序列

#define ll long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define vll vector<ll>
#define fi first
#define se second
const int maxn = 5000 + 5;
const int mod = 1e9 + 7;
int n;
int dp[maxn][maxn];
string a ;
ll calc ()
{
    memset(dp , 0 , sizeof dp);
    dp[0][0] = 1;
    for (int i = 1 ; i <= n ; i++){
        if (a[i - 1] == '('){
            for (int j = 1 ; j <= n ; j++)
                dp[i][j] = dp[i - 1][j - 1];
        }else {
            dp[i][0] = (dp[i - 1][0] + dp[i - 1][1]) % mod;
            for (int j = 1 ; j <= n ; j++)
                dp[i][j] = (dp[i - 1][j + 1] + dp[i][j - 1]) % mod;
        }
    }
    for (int i = 0 ; i <= n ; i++) if (dp[n][i]) return dp[n][i];
    return -1;
}
int main()
{
    ios::sync_with_stdio(false);
    cin >> a;
    n = a.size();
    ll l = calc();
    reverse(a.begin() , a.end());
    for (auto &g : a) if (g == '(') g = ')'; else g = '(';
    ll r = calc();
    cout << l * r % mod << endl;
    return 0;
}
  1. 时间显示

int main()
{
    long long n, m[100];
    cin >> n;
    for (int e = 1; e <= n; e++)
        cin >> m[e];
    for (int e = 1; e <= n; e++)
    {
        int a = m[e]/1000 / 60 / 60 % 24, b = m[e]/1000 / 60%60, c = m[e]/1000 % 60;
        if (a < 10)
            cout << 0 << a;
        else
            cout << a;
        cout << ":";
            if (b < 10)
                cout << 0 << b;
            else
                cout << b;
            cout << ":";
            if (c < 10)
                cout << 0 << c;
            else
                cout << c;
    }



}
  1. 杨辉三角

typedef long long LL;
int n;
LL C(int a, int b)
{
    
    LL res = 1;
    for(int i = a, j = 1; j <= b; i --, j ++)
    {
    
        res = res * i / j;
        if(res > n)
            return res;  
    }
    return res;
}
bool check(int k)
{
    
    int l = 2 * k, r = max(n,l);
    while(l < r)
    {
    
        int mid = l + r >> 1;
        if(C(mid, k) >= n) r = mid;
        else l = mid + 1;
    }
    if(C(r, k) != n)
        return false;
    cout << 1ll*(r + 1) * r / 2 + k + 1 << endl;
    return true;
}
int main()
{
    
    cin >> n;
    for(int i = 16; ; i--)
        if(check(i))
            break;
    return 0;
}
  1. 双向排序


typedef pair<int,int> PII;
PII s[100005];
int n,m;
int top;
int ans[100005];
int main() {
    cin>>n>>m;
    int x,y;
    for(int i=1; i<=m; ++i) {
        scanf("%d%d",&x,&y);
        if(!x) 
        {
            if(top&&s[top].first==0) {
                y=max(y,s[top--].second);
            }
            while(top>=2&&s[top-1].second<=y) { 
                top-=2;
            }
            s[++top]= make_pair(0,y);
        }else if(top)
        {
            if(top&&s[top].first==1) {
                y=min(y,s[top--].second);
            }
            while(top>=2&&s[top-1].second>=y) {
                top-=2;
            }
            s[++top]= make_pair(1,y);
        }
    }
    int k=n,l=1,r=n;
    for(int i=1; i<=top; ++i) {
        if(s[i].first==0) {
            while(r>s[i].second&&l<=r) ans[r--]=k--;
        } else {
            while(l<s[i].second&&l<=r) ans[l++]=k--;
        }
        if(l>r) break;
    }
    
    if(top%2!=0) {
        while(k>0) ans[l++]=k--;
    } else {
        while(k>0) ans[r--]=k--;
    }
    for(int i=1;i<=n;++i)
    {
        printf("%d ",ans[i]);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值