首页 > 其他分享 >1.31 蓝桥杯练习5题

1.31 蓝桥杯练习5题

时间:2024-01-31 23:22:47浏览次数:32  
标签:const int ll 练习 long 蓝桥 1.31 dp

1.31 蓝桥杯练习5题

退役哩,但是下学期还要打蓝桥。好久没写题脑袋空空,准备每天写几个练手。

1.[P8599 蓝桥杯 2013 省 B] 带分数

题意:\(100\) 可以表示为带分数的形式:\(100 = 3 + \frac{69258}{714}\)。

还可以表示为:\(100 = 82 + \frac{3546}{197}\)。

注意特征:带分数中,数字 \(1\) ~ \(9\) 分别出现且只出现一次(不包含 \(0\))。

类似这样的带分数,\(100\) 有 \(11\) 种表示法。

思路:解题的关键在于数字 \(1\) ~ \(9\) 分别出现且只出现一次。那么对于一个带分数,我们可以分成三个部分:整数,分子,分母。由于题目给的时限是3秒,可以进行9的全排列,然后把这个排列分成3份,看可行性即可。

注意,对于除法不好判断,可以转化为乘法。

因为\(a+\dfrac{b}{c} = n\)则当\((n-a)*c = b\)成立时候是合法的。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
int n,num[]={0,1,2,3,4,5,6,7,8,9};

int get(int l,int r)
{
    int res = 0;
    for(int i = l; i <= r; i++)
    {
        res *= 10;
        res += num[i];
    }
    return res;
}

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    cin>>n;
    int ans = 0;
    do{
        for(int i = 1;i <= 7; i++)
        {
            for(int j = i+1;j <= 8; j++)
            {
                int a = get(1,i),b = get(i+1,j),c = get(j+1,9);
                if((n-a)*c==b){
                   // cout<<"a = "<<a<<" b = "<<b<<" c = "<<c<<"\n";
                    ans++;
                }
            }
        }
    }while(next_permutation(num+1,num+10));

    cout<<ans<<"\n";
    return 0;
}

2.[P8787 蓝桥杯 2022 省 B] 砍竹子

题意:这天,小明在砍竹子,他面前有 \(n\) 棵竹子排成一排,一开始第 \(i\) 棵竹子的高度为 \(h_{i}\).

他觉得一棵一棵砍太慢了,决定使用魔法来砍竹子。魔法可以对连续的一段相同高度的竹子使用,假设这一段竹子的高度为 \(H\),那么使用一次魔法可以把这一段竹子的高度都变为 \(\left\lfloor\sqrt{\left\lfloor\frac{H}{2}\right\rfloor+1}\right\rfloor\), 其中 \(\lfloor x\rfloor\) 表示对 \(x\) 向下取整。小明想知道他最少使用多少次魔法可以让所有的竹子的高度都变为 \(1\)。

思路:思考怎样才能使用魔法次数尽量的少,那就是在变到1之前连续一样的数尽可能的多。那么我们可以先预处理出每一个竹子高度变为1所要的操作次数。我们考虑贪心的去砍,因为我们想要连续的一样的尽量的多,并且我们不能使得矮的变成高的,那么我们肯定是优先砍高的,其他的不会更优。

具体操作:先预处理出每棵竹子需要砍的次数,从高到低去砍,注意如果当前的和下一个是一样的操作次数,但是注意如果高度不一样我们还是不能一起使用魔法的,只能对它(和它之前一样高度的)单独用。如果一样的话就可以和后面的一起使用魔法(注意我们是找到第一个不连续的那个进行统计的)。具体细节看代码

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;
ll a[N],b[N],mx;
int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    ll n; cin>>n;
    for(int i = 1;i <= n; i++)
        cin>>a[i];
    for(int i = 1;i <= n; i++)
    {
        ll cnt = 0;
        ll t = a[i];
        while(t != 1)
        {
            cnt++;
            t = sqrt(t/2+1);
        }
        b[i] = cnt;
        mx = max(mx,b[i]);
    }
    ll cnt = 0;
    for(int i = mx;i > 0;i--)
    {
        for(int j = 1;j <= n; j++)
        {
            if(b[j] == i)
            {
                if(a[j] != a[j+1]) cnt++;//和后一个不一样,说明不可能有更多的连续的,需要用魔法
                b[j]--;//砍过一次了,操作次数-1
                a[j] = sqrt(a[j]/2+1);//高度变化
            }
        }
    }
    cout<<cnt<<"\n";

    return 0;
}

3.[P8597 蓝桥杯 2013 省 B] 翻硬币

题意:桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零),比如可能情形是 **oo***oooo,如果同时翻转左边的两个硬币,则变为 oooo***oooo。现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?

思路:这个题很简单啦,直接模拟就行了,因为题目说一定有解,那么需要翻动我就一定要翻。从前往后翻,同一组之后翻一次,这样是最优的。

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e5 + 10;

int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    string s,t; cin>>s>>t;
    s = "?" + s;
    t = "?" + t;
    int n = s.size(),cnt = 0;
    for(int i = 1;i < n; i++)
    {
        if(s[i] != t[i])
        {
            cnt++;
            s[i] = t[i];
            if(s[i+1]=='*')s[i+1] = 'o';
            else s[i+1] = '*';
        }
    }
    cout<<cnt<<"\n";


    return 0;
}

4.[P9242 蓝桥杯 2023 省 B] 接龙数列

题意:对于一个长度为 \(K\) 的整数数列:\(A_{1},A_{2},\ldots,A_{K}\),我们称之为接龙数列当且仅当 \(A_{i}\) 的首位数字恰好等于 \(A_{i-1}\) 的末位数字(\(2 \leq i \leq K\))。

例如 \(12,23,35,56,61,11\) 是接龙数列;\(12,23,34,56\) 不是接龙数列,因为 \(56\) 的首位数字不等于 \(34\) 的末位数字。所有长度为 \(1\) 的整数数列都是接龙数列。

现在给定一个长度为 \(N\) 的数列 \(A_{1},A_{2},\ldots,A_{N}\),请你计算最少从中删除多少 个数,可以使剩下的序列是接龙序列?

思路:一开始我不知道怎么去写,最少次数,感觉可能是二分?但是check函数写不了啊。看到数据范围\(1e5\),可能是\(O(N)\)的,总共就\(9\)个数字,那么考虑\(dp[i]\)表示以\(i\)结尾最多能接上多少个?答案就是\(min(n-dp[1~9])\)

转移方程怎么写嘞?因为我们只用考虑首尾就行了,假设当前的首是\(s\),尾是\(e\)。

考虑当前这个要还是不要,如果要接在前面,那么前一个的尾要是\(s\),接上了的话答案就是\(dp[s]+1\)。如果不要这个就是直接继承\(dp[e]\)即可。

于是\(dp[e] = max(dp[e],dp[s]+1)\)

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 1e5 + 10;
ll dp[N];
int main()
{
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    for(int i = 1;i <= n; i++)
    {
        string s; cin>>s;
        int len = s.size();
        dp[s[len-1]-'0'] = max(dp[s[len-1]-'0'],dp[s[0]-'0']+1);
    }

    ll ans = 0;
    for(int i = 0;i <= 9; i++)
        ans = max(ans,dp[i]);

    cout<<n-ans<<"\n";
    return 0;
}

5.[P8784 蓝桥杯 2022 省 B] 积木画

题意:小明最近迷上了积木画,有这么两种类型的积木,分别为 \(I\) 型(大小为 \(2\) 个单位面积) 和 \(L\) 型 (大小为 \(3\) 个单位面积):

I 型积木

同时,小明有一块面积大小为 \(2 \times N\) 的画布,画布由 \(2 \times N\) 个 \(1 \times 1\) 区域构成。小明需要用以上两种积木将画布拼满,他想知道总共有多少种不同的方式? 积木可以任意旋转,且画布的方向固定。

思路:这个题是个图形\(dp\),统计方案数。我们一步步来考虑。

\(2\times n\)的地方放积木,问方案数,考虑怎么放感觉会很困难,我们考虑最后一步要怎么放是不是容易很多呢?
冬天手冷,字略丑QAQ..hh

image

综上所述:答案就是:\(F[i] = 2*F[i-1]+F[i-3]\)

其中:\(F[1] = 1,F[2] = 2,F[3] = 5\)

// AC one more times
// nndbk
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod = 1e9 + 7;
const int N = 2e7 + 10;
ll f[N];
int main()
{   
    ios::sync_with_stdio(false);   cin.tie(nullptr), cout.tie(nullptr);
    int n; cin>>n;
    f[1] = 1,f[2] = 2,f[3] = 5;
    for(int i = 4;i <= n; i++)
    {
        f[i] = (2*f[i-1]%mod+f[i-3])%mod;
    }

    cout<<f[n]<<"\n";

    return 0;
}

标签:const,int,ll,练习,long,蓝桥,1.31,dp
From: https://www.cnblogs.com/nannandbk/p/18000343

相关文章

  • 2024.1.31寒假每日总结22
    算法题:2670.找出不同元素数目差数组-力扣(LeetCode)①NLP(NaturalLanguageProcessing),也就是人们常说的「自然语言处理」,就是研究如何让计算机读懂人类语言,即将人的自然语言转换为计算机可以阅读的指令。②分词是NLP任务的一个起始,分词的好坏会影响整体模型的好坏。并且分......
  • 闲话1.31
    haosen不在的第三天,想她......
  • 24.1.31(读后感)
    第四章两人合作4.1代码规范包括代码风格规范和代码设计规范4.2代码风格规范代码风格原则:简明、易读、无二异性缩进:4个空格,而不是TAB行宽:限定为100字符括号断行与空白的{}行分行命名:匈牙利命名法下划线:分隔变量名字中的作用域标注和变量语义大小写(Pascal形式和Camel......
  • 1.31寒假每日总结22
    1)NLP基本概念①NLP(NaturalLanguageProcessing),也就是人们常说的「自然语言处理」,就是研究如何让计算机读懂人类语言,即将人的自然语言转换为计算机可以阅读的指令。②分词是NLP任务的一个起始,分词的好坏会影响整体模型的好坏。并且分词不一样,语义不一样。1. 中国北京大......
  • 1.31
    2月份rp++机房里的人能不能不要那么典啊......
  • 2024年1月31日练习答案
    目录P505【基础】寻找祖先P541【基础】吃西瓜(watermelon)P832【提高】AtoBP841【入门】s01串P505【基础】寻找祖先给出充足的父子关系,请你编写程序找到某个人的最早的祖先。规定每个人的名字都没有空格,且没有任意两个人的名字相同。最多可能有1000组父子关系,总人数......
  • 美赛2023C练习-做题笔记
    代码:clc;TC=ProblemCDataWordle;%数据处理noC=TC(:,1);wordC=TC(:,2);dataC=TC(:,3:11);no=cell2mat(noC);data=cell2mat(dataC);L=size(wordC);L=L(1);word=[];%原表格有错误,根据网络数据进行修正wordC{36}="clean";wordC{247}="trash";%修正endfori=1:L......
  • 每日一练 | 华为认证真题练习Day174
    1、下面关于OSPF报文验证描述错误的是:A.AR2200支持的验模式按加密算协议中规定的法不同分为NULLSIMPLEMD5以及HMAC-MD5B.AR2200支持两种认证方式区域验证和接口验证C.当区域验证方式和接口验证方式同时存在时,优先使用区域验证D.只有通过验证的OSPF报文才能接受,否则将不能正常......
  • 2024 蓝桥杯模拟赛 2 (div1+div2)
    A.根据题目模拟#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=1e5+10;voidsolve(){inta,p;cin>>a>>p;if(p<16)a=max(0ll,a-10);elseif(p>20){inttmp=p-20;a=max(0ll,a-tmp)......
  • 每日一练 | 华为认证真题练习Day173
    1、关于OSPF的AS-External-LSA中LSA头部信息描述错误的是:A.LinkStateID表示目的网络地址。B.AdvertisingRouter表示ASBR的RouterID。C.Netmask表示目的网段的网络掩码。D.FORWARDINGADDRESS永远为0.0.0.02、下面关于EGP和IGP描述错误的是A.IGP是运行于AS内部的路由协......