c++/c蓝桥杯模拟赛题解,非常详细
质因数
1、填空题
【问题描述】
如果一个数 p 是个质数,同时又是整数 a 的约数,则 p 称为 a 的一个质因数。
请问 2024 有多少个质因数。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分.
写一个判断质数和约数的函数判断即可
约数判断可以直接使用c++的__gcd(最大公因数)函数,当然也可以自己造轮子,另外注意,最小公倍数=最大公约数-a*b
质数判断,暴力解法直接循环即可
bool key(int n){ if(n==1)return false; if(n==2)return true; for(int i=2;i<sqrt(n);i++){ if(n%i==0)return false; } return true;}
答案:3
开根
2、填空题
【问题描述】
对于一个整数 n ,我们定义一次开根变换会将 n 变为开根号后的整数部分。即变为平方和不超过 n 的数中的最大数。
例如,20 经过开根变换将变为 4 ,如果再经过一次开根变换将变为 2 ,如果再经过一次开根变换将变为 1 。
请问,2024经过多少次开根变换后会变为 1 ?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
这道题就不过多解释了,直接判断即可,直至==1退出循环
#include<bits/stdc++.h>using namespace std;#define int long longint a,b;int cnt=0;signed main(){int n=2024;while(sqrt(n)!=1){cnt++;n=sqrt(n);}cout<<cnt; return 0;}
答案:4
立方体
3、填空题
【问题描述】
小蓝有很多 1x1x1 的小立方体,他可以使用多个立方体拼成更大的立方体。
例如,小蓝可以使用 8 个小立方体拼成一个大立方体,每边都是 2 个。
又如,小蓝可以使用 27 个小立方体拼成一个大立方体,每边都是 3 个。
现在,小蓝有 2024 个小立方体,他想再购买一些小立方体,用于拼一个超大的立方体,要求所有的小立方体都用上,拼成的大立方体每边长度都相等。
请问,小蓝最少需要购买多少个小立方体?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。
就是一个次方的问题,直接可以用计算机得到:13^3=2197,2197-2024=173
答案:173
日期问题
4、填空题
【问题描述】
如果一个日期的日期以 1 结尾(1日、11日、21日、31日)且为星期一,则称这个日期为一好日期。
请问从 1901 年 1 月 1 日至 2024 年 12 月 31 日总共有多少个一好日期。
提示:1901 年 1 月 1 日是星期二。
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分.
模拟即可,从开始直接循环到结束,三层循环来控制年月日,开一个weekday变量控制周
#include <stdio.h>#include <stdbool.h>// 判断是否是闰年bool is_leap_year(int year) { return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0);}// 获取某个月的天数int get_days_in_month(int year, int month) { int days_in_month[] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}; if (month == 2 && is_leap_year(year)) { return 29; // 闰年二月 } return days_in_month[month - 1];}int main() { int count = 0; // 好日期计数 int weekday = 2; // 1901 年 1 月 1 日是星期二(1=星期一,2=星期二,...,7=星期日) int year = 1901, month = 1, day = 1; // 遍历从 1901 年 1 月 1 日到 2024 年 12 月 31 日 for (year = 1901; year <= 2024; year++) { for (month = 1; month <= 12; month++) { int days_in_month = get_days_in_month(year, month); for (day = 1; day <= days_in_month; day++) { // 检查是否为好日期 if (weekday == 1 && (day == 1 || day == 11 || day == 21 || day == 31)) { count++; } // 更新星期 weekday = (weekday % 7) + 1; } } } // 输出结果 printf("%d\n", count); return 0;}
答案:762
异或运算
5、填空题
【问题描述】
两个数按位异或是指将这两个数转换成二进制后,最低位与最低位异或作为结果的最低位,次低位与次低位异或作为结果的次低位,以此类推。
例如,3 与 5 按位异或值为 6 。
小蓝有以下 30 个整数:
9226, 4690, 4873, 1285, 4624, 1596, 6982, 590, 8806, 121, 8399, 8526, 5426, 64, 9655, 7705, 3929, 3588, 7397, 8020, 1311, 5676, 3469, 2325, 1226, 8203, 9524, 3648, 5278, 8647.
小蓝想找一个整数 V ,使得 V 与这 30 个数分别异或后,得到的 30 个数的平方和最小。请问平方和最小是多少?
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分
暴力即可,注意开longlong
#include<bits/stdc++.h>using namespace std;#define int long longint mi=1e16;int sum[30];int arr[30]={9226, 4690, 4873, 1285, 4624, 1596, 6982, 590, 8806, 121, 8399, 8526, 5426, 64, 9655, 7705, 3929, 3588, 7397, 8020, 1311, 5676, 3469, 2325, 1226, 8203, 9524, 3648, 5278, 8647};signed main(){for(int i=1;i<1e7;i++){int shix=0;for(int j=0;j<30;j++){sum[j]=(i^arr[j]);} for(int j=0;j<30;j++){shix+=sum[j]*sum[j];}if(shix<mi){mi=min(mi,shix);cout<<i<<"gai"<<endl;}}cout<<mi; return 0;}
答案:1070293541
后面大题code:
停车场停车
【问题描述】
小蓝在一个停车场停车。
停车场的收费规则为:每 15 分钟收费 2 元,不满 15 分钟的不收费。
小蓝总共停车 n 分钟,请问收费总额是多少?
【输入格式】
输入一行包含一个整数 n ,表示小蓝停车的时长。
【输出格式】
输出一行包含一个整数,表示停车费用。
【样例输入】
150
【样例输出】
20
【样例输入】
2024
【样例输出】
268
【评测用例规模与约定】
对于所有评测用例,1 <= n <= 10000。
向下取整即可
#include <bits/stdc++.h>#define int long longusing namespace std;int tmp;signed main(){int n;cin>>n;if(n<15)cout<<"0";else{cout<<(n/15)*2;} return 0;}
非零数减一
【问题描述】
小蓝有一个整数 n ,每次操作,可以将这个整数的每个非零数位减少 1 。
请问经过多少次操作,这个数会变为 0 。
例如,整数 2024 经过一次操作变为 1013,再经过一次操作变为 2 (即0002),再经过两次操作变为 0 ,总共经过 4 次变换变为 0 。
【输入格式】
输入一行包含一个整数 n 。
【输出格式】
输出一行,包含一个整数,表示答案。
【样例输入】
2024
【样例输出】
4
【评测用例规模与约定】
对于 50% 评测用例,1 <= n < 10000。
对于所有评测用例,1 <= n < 1000000000。
找出最大的非零数,即要减的最大次数
#include <bits/stdc++.h>#define int long longusing namespace std;int tmp;signed main(){char c='0';int n;cin>>n;string a=to_string(n);for(int i=0;i<a.length();i++){if(c<a[i])c=a[i];}cout<<c; return 0;}
减法运算
【问题描述】
小蓝有一个减法式子,形如 a-b,其中 a 和 b 都是非负整数(不保证结果非负)。
请编程处理这个式子,输出运算结果。
【输入格式】
输入一行包含一个减法表达式,式子中仅含数字字符和一个减号。
【输出格式】
输出一行包含一个整数,表示运算结果。
【样例输入】
2024-1949
【样例输出】
75
【样例输入】
20-24
【样例输出】
-4
【评测用例规模与约定】
对于 50% 的评测用例,减法中的两个数都是不超过 10000 的非负整数。
对于所有评测用例,减法中的两个数都是不超过 1000000000 的非负整数。
字符串转数字计算即可stoi(字符串转int)stoll(字符串转long long)
#include <bits/stdc++.h>#define int long longusing namespace std;int tmp;signed main(){string res1="",res2="";string a;cin>>a;int index=a.find("-");for(int i=0;i<index;i++)res1+=a[i];for(int i=index+1;i<a.length();i++)res2+=a[i];int cnt1=stoll(res1);int cnt2=stoll(res2);cout<<cnt1-cnt2; return 0;}
间隔为k
小蓝有一个长度为 n 的整数数列 a[1], a[2], …, a[n] 。
对于一个给点的整数 k ,小蓝想找到相邻间隔为 1 的 k 个数 a[p], a[p+2], a[p+4], …, a[p+2k-2],使得他们的和最大。其中 1 <= p <= n-2k+2。
给定数列和 k ,请问给出最大的和。
【输入格式】
输入的第一行包含一个整数 n 。
第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示 a[1], a[2], …, a[n] 。
第三行包含一个整数 k 。
【输出格式】
输出一行,包含一个整数,表示答案。
首先求出题意给的区间,然后循环找最大值即可
#include <bits/stdc++.h>#define int long longusing namespace std;int mx=0;int arr[100010];signed main(){int n;cin>>n;for(int i=1;i<=n;i++)cin>>arr[i];int k;cin>>k;int r=n-2*k+2;for(int i=1;i<=r;i++){int sum=0;//sum要在这里进行初始化 for(int j=i;j<=i+2*k-2;j+=2){sum+=arr[j];}if(sum>mx){mx=max(mx,sum);}}cout<<mx; return 0;}
钩子
【问题描述】
小蓝有一个长度为 n 的整数序列 a[1], a[2], …, a[n] 。
他希望从中找出一个最长的子序列,形成一个勾的形状(√)。
即找到 1 <= p[1] < p[2] < … < p[k] <= n,满足 a[p[1]] > a[p[2]] > a[p[3]] > … > a[p[x]] < a[p[x+1]] < … < a[p[k]] 。其中 k 是子序列的长度,x 是勾中最小的位置。目标是使得 k 最大。
请找出最大的勾的长度。
【输入格式】
输入的第一行包含一个整数 n 。
第二行包含 n 个整数,相邻数之间使用一个空格分隔,依次表示 a[1], a[2], …, a[n] 。
【输出格式】
输出一行,包含一个整数,表示答案。
【样例输入】
10
2 1 4 7 4 8 3 6 4 7
【样例输出】
5
【样例说明】
当 p = (4,5,7,9,10) 时,a[4] , a[5] , a[7] , a[9] , a[10] 可形成一个长度为 5 的勾:7,4,3,6,7。
【评测用例规模与约定】
对于 30% 的评测用例,1 <= n <= 20 , 1 <= a[i] <= 100 。
对于 60% 的评测用例,1 <= n <= 100 , 1 <= a[i] <= 1000 。
对于所有评测用例,1 <= n <= 1000 , 1 <= a[i] <= 10000 。
简单动态规划
我们使用两层循环遍历序列中的每个元素。对于每个元素 a[i]
,我们再遍历它之前的所有元素 a[j]
(j < i
)。如果 a[j]
大于 a[i]
,这意味着我们可以通过将 a[i]
接到 a[j]
后面来形成一个更长的递减子序列。因此,我们更新 decreasing[i]
为 decreasing[j] + 1
和当前 decreasing[i]
中的较大值
#include <iostream>#include <vector>#include <algorithm>using namespace std;int main() { int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; i++) { cin >> a[i]; } if (n < 3) { cout << 0 << endl; return 0; } vector<int> decreasing(n, 1); vector<int> increasing(n, 1); // 计算每个位置之前的最长递减子序列 for (int i = 0; i < n; i++) { for (int j = 0; j < i; j++) { if (a[j] > a[i]) { decreasing[i] = max(decreasing[i], decreasing[j] + 1); } } } // 计算每个位置之后的最长递增子序列 for (int i = n - 1; i >= 0; i--) { for (int j = i + 1; j < n; j++) { if (a[j] > a[i]) { increasing[i] = max(increasing[i], increasing[j] + 1); } } } int max_length = 0; for (int i = 0; i < n; i++) { if (decreasing[i] > 1 && increasing[i] > 1) { max_length = max(max_length, decreasing[i] + increasing[i] - 1); } } cout << max_length << endl; return 0;}