小工具知识网

当前位置: 首页 > 行业知识 > 2023年第十四届蓝桥杯大赛软件类省赛C/C++大学A组真题

行业知识

2023年第十四届蓝桥杯大赛软件类省赛C/C++大学A组真题

2026-11-06 17:54:09 来源:互联网转载

2023年���十四届蓝桥杯大赛软件类省赛C/C++大学A组部分真题和题解分享

文章目录

  • 蓝桥杯2023年第十四届省赛真题-平方差
    • 思路题解
    • 蓝桥杯2023年第十四届省赛真题-更小的数
      • 思路题解
      • 蓝桥杯2023年第十四届省赛真题-颜色平衡树
        • 思路题解
        • 蓝桥杯2023年第十四届省赛真题-买瓜
          • 思路题解

            蓝桥杯2023年第十四届省赛真题-平方差

            题目描述

            给定 L, R,问 L ≤ x ≤ R 中有多少个数 x 满足存在整数 y,z 使得 x = y2 − z2。

            输入格式

            输入一行包含两个整数 L, R,用一个空格分隔。

            输出格式

            输出一行包含一个整数满足题目给定条件的 x 的数量。

            样例输入

            1 5

            样例输出

            4

            提示

            1 = 12 − 02 ;

            3 = 22 − 12 ;

            4 = 22 − 02 ;

            5 = 32 − 22 。

            对于 40% 的评测用例,LR ≤ 5000 ;

            对于所有评测用例,1 ≤ L ≤ R ≤ 109 。

            思路题解

            解题思路:

            • 规律:只有当x为奇数或4的倍数时才能拆分为两个数的平方差。

              注意事项:

            • 刚开始用c++写循环的时候,有一个样例会超时,故进一步寻找规律:F(X)=x/4+(x+1)/2,该式代表不大于x的满足条件的数的个数,用F®-F(L-1)即为L-R之间(大于等于L,小于等于R)满足条件的数的个数。
              #includeusing namespace std;int F(int x) {    return x / 4 + (x + 1) / 2;//不大于x的满足条件的数的个数}int main() {    int l = 0, r = 0;    cin >> l >> r;    cout  s[r]则满足条件,答案的个数+1。 

              详细解释:考虑s的所有子串[l,r], l即left,是子串的起始下标,r即right是子串的末尾下标,判断s[l] 和 s[r]的大小关系:

              • 若s[l] > s[r]则该子串反转后,新串原串,不满足条件。

                注意事项:

                • 注意l和r的取值范围(详见代码注释)。
                  #include#includeusing namespace std;string s;int F(int l, int r) {    while (l  s[r])return 1;//如果s[l] > s[r],反转后满足条件 新字符串 l++;r--; }//如果s[l] == s[r],两边同时缩小区间。        else break;//如果s[l]  s;    int n = s.length();//n是字符串长度    int ans = 0;//记录答案    for (int l = 0;l //l即left是子串的起始下标,从0开始到n-2(子串长度至少为2,最右侧的最小子串下标为[n-2,n-1],故l最多到n-2)        for (int r = n - 1;r  l;r--) {//r即right是子串的末尾下标,从s的最末下标n-1到l+1。            if(F(l,r))ans++;        }    }    cout     for(auto entry:cnt_nb){        int c=entry.first,count = entry.second;        cnt[c] += count;    }}/*对树进行dfs搜索,树的根节点为i,并返回该子树的各节点颜色计数结果*/map    int sz = g[i].size();    map         cnt[c[i]] = 1;         ans++;         return cnt;    }    /*如果不是叶子节点*/    //将根节点的颜色加入cnt    cnt[c[i]]=1;    //遍历根节点的所有子树,并将子树的计数结果累加到cnt中    for(int j=0;j        int nb = g[i][j];        map        //存在一种颜色数量不等,直接返回        if(entry.second != count) return cnt;     }    //各颜色的数量相等,结果+1    ans++;    //返回计数结果    return cnt;}int main(){    int n;    cinn;    vector g[N];     int c[N]; //每个节点的颜色    for(int i=0;i        int f;        cin>c[i]>>f;        if(f>=1){            g[f-1].push_back(i); //记录节点f的子节点i(节点编号从0开始)        }    }    dfs(g,c,0);    coutm 

                  但是这样仍然会超时,还可以将重量数组降序排列,使得更快剪枝。还可以创建一个重量数组的后缀数组suf,这样在搜索时可以利用其剪枝:若当前重量加上剩余的所有瓜重量之和小于要求的重量,剪枝。

                  #include#includeusing namespace std;const int N = 30; int INF = 100;int n,m;int v[N]; //重量数组long suf[N+1]; //重量数组的后缀数组int ans = INF; //将结果初始化为INF/*dfs搜索,参数分别表示当前层数,当前重量之和,切瓜的次数*/void dfs(int pos,long sum,int cnt){    if(sum==m){ //找到了一个结果        ans = min(ans,cnt);        return;    }    //剪枝    if(pos>=n || cnt>=ans || sum>m || sum+suf[pos]    ios::sync_with_stdio(false);    cin.tie(0),cout.tie(0);    cin>n>>m;    m*=2; //总重量乘2    for(int i=0;i>v[i],v[i]*=2;    sort(v,v+n,greater());    for(int i=n-1;i>=0;i--) suf[i] = suf[i+1]+v[i];    dfs(0,0,0);    if(ans==INF) cout

上一篇:1. MySQL 5.7安装部署

下一篇:买了虚拟主机怎么使用?