🎉🎉 目前持续总结更新,请持续关注!!! 🎉🎉
💗 大家好🤗🤗🤗,我是左手の明天!💗
📆 最近更新:2022 年 4 月 18 日,左手の明天的第 229 篇原创博客
🥇 更新于专栏:蓝桥杯预备营
🌟🌟 往期必看 🌟🌟
【蓝桥杯预备营集结一】软件类 C/C++ 预备试题分析及解答
【蓝桥杯预备营集结二】软件类 C/C++ 预备试题分析及解答
【蓝桥杯预备营集结三】软件类 C/C++ 预备试题分析及解答
【蓝桥杯预备营集结四】软件类 C/C++ 预备试题分析及解答
【蓝桥杯预备营集结五】第十三届蓝桥杯模拟赛 C/C++ 试题分析及解答
【蓝桥杯预备营集结六】软件类 C/C++ 预备试题分析及解答
【蓝桥杯预备营集结七】软件类 C/C++ 预备试题(分支结构+循环结构类)分析及解答
目录
👍👍👍👍👍👍
🌟🌟 预祝各位在每一届中能够得到好的名次 🌟🌟
🚩亲密数
⭐️问题描述
假设有 a、b 两个数,若 a 的所有因子之和等于 b,b 的所有因子之和等于 a,并且 a 不等于 b,则称 a 和 b 是一对亲密数。如 284 和 220 就是一对亲密数。
⭐️代码
#include<stdio.h>
int main()
{
int a,b,i,n;
for(a=1;a<=10000;a++)
{
for(b=0,i=1;i<=a/2;i++)
if(a%i==0)
b+=i;
for(n=0,i=1;i<=b/2;i++)
if(b%i==0)
n+=i;
if(n==a&&a!=b&&a<b)
printf("%d-%d\n",a,b);
}
return 0;
}
#include <stdio.h>
#include <stdlib.h>
int g[100000];
int main()
{
int a, b, m, n, k;
scanf("%d %d", &a, &b);
for (m = a; m <= b; m++)
{
for (n = 2, k = 1; n <= m / 2; n++)
{
if (m % n == 0)
{
k = k + n;
}
}
g[m] = k;
}
for (m = a; m < b;m++)
{
for (n = m + 1; n <= b; n++)
{
if (g[m] == n && g[n] == m)
{
printf("%d %d\n", m, n);
}
}
}
return 0;
}
🚩世纪末的星期
⭐️问题描述
曾有邪教称 1999 年 12 月 31 日是世界末日。当然该谣言已经不攻自破。还有人称今后的某个世纪末的 12 月 31 日䊵如果是星期一则会....
有趣的是 任何一个世纪末的年份的 12 月 31 日都不可能是星期一!!
于是 “谣言制造商”又修改为星期日......
1999 年的 12 月 31 日是星期五,请问,未来哪一个离我们最近的一个世纪末年即 xx99年的 12 月 31 日正好是星期天,即星期日
请回答该年份,只写这个 4 位整数,不要写 12 月 31 等多余信息
⭐️思路
主要还是判断闰平年,已知1999年12月31日是星期五,初始化day=5;因为是qiu最后一天是 星期几,所以直接判断闰平年,加上这一年的天数,然后判断是否可以整除7 即可,最后添加附加条件,世纪末年为xx99,所以year%100为99即可。
⭐️代码
#include<stdio.h>
int main ()
{
int day=5;
int year=2000;
do{
if(year%4==0&&year%100!=0||year%400==0)
day=day%7+366;
else
day=day%7+365;
if(day%7==0&&year%100==99)
{
printf("%d",year);
break;
}
year++;
}while(year<=9999);
return 0;
}
⭐️结果
答案:2299
🚩啤酒和饮料
⭐️问题描述
啤酒每罐 2.3 元,饮料每罐 1.9 元。小明买了若干啤酒和饮料,一共花了 82.3 元。我们还知道他买的啤酒比饮料的数量少,请你计算他买了几罐啤酒。
⭐️思路分析
分析:题目本身循环就行
主要在于如何判断两个浮点类型的数据相等
fabs():取绝对值函数 存放在math.h里
判断|a-b|<=0.0000000000001即可
⭐️代码
#include<iostream>
using namespace std;
#include<math.h>
int main()
{
double pi,yi;
for(pi=0;pi<=50;pi++)
{
for(yi=pi+1;yi<=50;yi++)
{
if(fabs(2.3*pi+1.9*yi-82.3)<=1e-8)
cout<<pi<<endl;
}
}
return 0;
}
⭐️结果
答案:11
🚩高斯日记
⭐️问题描述
大数学家高斯有个好习惯:无论如何都要记日记。他的日记有个与众不同的地方,他从不注明年月日,而是用一个整数代替,比如:4210
后来人们知道,那个整数就是日期,它表示那一天是高斯出生后的第几天。这或许也是个好
习惯,它时时刻刻提醒着主人:日子又过去一天,还有多少时光可以用于浪费呢?
高斯出生于:1777 年 4 月 30 日。
在高斯发现的一个重要定理的日记上标注着:5343,因此可算出那天是:1791 年 12 月 15
日。
高斯获得博士学位的那天日记上标着:8113 请你算出高斯获得博士学位的年月日。
提交答案的格式是:yyyy-mm-ddy,例如:1980-03-21
⭐️解题思路
1、我们计算出高斯出生的那一天到出生年末的时间t1,我们用总的天数t减去t1,这样方便我们计算年数;
2、我们对接下来的每年相加,直到得到第一个天数大于t的年份,则该年份就是我们要求出的年份,按照同样的方法求出月份;
3、天数就是t减去以上的时间剩下的结果,还要注意特定的输出格式,输出结果中当天数和月份为个位数的时候,不是直接输出一个数,而是前面带有0,因此应对输出进行控制。
⭐️代码
#include<iostream>
#include<iomanip>
using namespace std;
int a[2][12]={{31,28,31,30,31,30,31,31,30,31,30,31},{31,29,31,30,31,30,31,31,30,31,30,31}}; //存储闰年和非闰年的各月份天数
int b[2]={365,366}; //存储闰年和非闰年的各年份的天数
int judge(int year) //判断平年闰年的函数
{
if(year%400==0||year%4==0&&year%100!=0)
return 1; //是闰年
else
return 0; //非闰年
}
void show(int year,int month,int day) //输出格式控制函数
{
cout<<year<<"-";
cout<<setw(2)<<setfill('0')<<month<<"-"; //对于一位数的月份前面补0
cout<<setw(2)<<setfill('0')<<day<<endl; //对于一位数的天数前面补0
}
int main()
{
int year=1777;
int month=4;
int day=30;
int total=8113;
int num=1;
while(++month<=12)
num += a[0][month-1]; //将1777年的剩余天数减去(即先存储在num中)
month=0;day=0; //月份和天数清零
while((num+=b[judge(++year)])<=total);
num -= b[judge(year)]; //找到了对应的年份
while((num+=a[judge(year)][++month])<=total);
num -= a[judge(year)][month]; //找到了对应的月份
day = total - num; //找到对应的天数
show(year,month,day); //将结果输出
}
⭐️结果
答案: "1799-07-16"
🚩排它平方数
⭐️问题描述
小明正看着 203879 这个数字发呆。 原来,203879 * 203879 = 41566646641 这有什么神奇呢?仔细观察,203879 是个 6 位数,并且它的每个数位上的数字都是不同的,并且它平方后的所有数位上都不出现组成它自身的数字。具有这样特点的 6 位数还有一个,请你找出它!
再归纳一下筛选要求:
1. 6 位正整数
2. 每个数位上的数字不同
3. 其平方数的每个数位不含原数字的任何组成数位
答案是一个 6 位的正整数。
⭐️代码
#include <iostream>
using namespace std;
int main()
{
int ii[6];
for (long long int i = 123456; i < 987654; i++)
{
int a = 1;//标记第2个要求是否通过
int b = 1;//标记第3个要求是否通过
int k = 0;
long long int h = i;
while (h)//记录每一位数字
{
ii[k++] = h % 10;
h /= 10;
}
long long int hi = i;
int t = 0;//记录位数
while (hi)//判断是否每一位都不同
{
int hh = hi % 10;
for (int j = 0; j < 6; j++)
{
if (t != j && hh == ii[j])
{
a = 0;
break;
}
}
if (a == 0) break;
hi /= 10;
t++;
}
if (a == 0)continue;
long long int s = i * i;
while (s)//判断是否平方和不重复原来的数
{
int ss = s % 10;
for (int jj = 0; jj < 6; jj++)
{
if (ss == ii[jj])
{
b = 0;
break;
}
}
if (b == 0)
break;
s /= 10;
}
if (b == 0)
continue;
cout << i << endl;
}
}
⭐️结果
答案:639172
🚩换硬币
⭐️问题描述
想兑换100元零钱,有1元、2元、5元、10元四种面值,总有多少种兑换方法?
⭐️解题思路
本题可以采用多种方法求解。最容易理解的应该就是暴力穷举和递归求解。
⭐️方法一:暴力穷举
100元换成1元,2元,5元,10元四种面值,那么考虑四种临界情况:
如果全部换成1元硬币, 则可换100个。
如果全部换成2元硬币, 则可换50个。
如果全部换成5元硬币, 则可换20 个。
如果全部换成10元硬币,则可换10个。
所以穷举范围就很清楚了,如果定义变量a,b,c,d分别表示1元,2元,3元,4元硬币的个数。那么:0<=a<=100; 0<=b<=50 ; 0<=c<=20 ; 0<=d<=10 ;
#include <stdio.h>
int main()
{
int g_count=0;
int a,b,c,d;
for(a=0; a<=100; a++)
{
for(b=0; b<=50; b++)
{
for(c=0; c<=20; c++)
{
for(d=0; d<=10; d++)
{
if(100==a+2*b+5*c+10*d)
{
g_count++;
}
}
}
}
}
printf("%d\n",g_count);
return 0;
}
⭐️方法二:递归求解
#include <iostream>
using namespace std;
const int N = 100;
int dimes[] = {1, 2, 5, 10};
int arr[N+1] = {1};
int coinExchange(int n, int m) //递归方式实现,更好理解
{
if (n == 0) //跳出递归的条件
return 1;
if (n < 0 || m == 0)
return 0;
return (coinExchange(n, m-1) + coinExchange(n-dimes[m-1], m));
//分为两种情况:换取当前面值的情况 + 没有换取当前面值的情况
//如果没有换当前硬币,那么是多少?加上,如果换了当前硬币,总值减少,此时又是多少种兑换方法?
}
int main()
{
int num=coinExchange(N, 4);
cout<<num<<endl;
return 0;
}
🚩翻硬币
⭐️问题描述
小明正在玩一个“翻硬币”的游戏。
桌上放着排成一排的若干硬币。我们用 * 表示正面,用 o 表示反面(是小写字母,不是零)。
比如,可能情形是:oo*oooo
如果同时翻转左边的两个硬币,则变为:oooo***oooo
现在小明的问题是:如果已知了初始状态和要达到的目标状态,每次只能同时翻转相邻的两个硬币,那么对特定的局面,最少要翻动多少次呢?
我们约定:把翻动相邻的两个硬币叫做一步操作,那么要求:
输入格式
两行等长的字符串,分别表示初始状态和要达到的目标状态。每行的长度<1000
输出格式
一个整数,表示最小操作步数。
输入样例1:
**********
o****o****
输出样例1:
5
输入样例2:
*o**o***o***
*o***o**o***
输出样例2:
1
⭐️思路分析
我们找开始的字符串和目标字符串的相邻的两个不同,进行相减,就能得到从上面到下面的字符串需要进行多少步,然后再继续找下一个两个不同,以此类推就可以得到答案了!!
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
using namespace std;
bool res=false;
int index1;
int sum = 0;
int main() {
string start;
string target;
cin >> start >> target;
int len = start.size();
for (int i = 0; i < len; i++) {
if (start[i] != target[i]) {
if (res == false) {
index1 = i;
res = true;
}
else {
sum += i - index1;
res = false;
}
}
}
cout << sum << endl;
return 0;
}
🚩三部排序
⭐️问题描述
一般的排序有许多经典算法,如快速排序、希尔排序等。 但实际应用时,经常会或多或少有一些特殊的要求。我们没必要套用那些经典算法,可以根据实际情况建立好的解法。
比如,对一个整型数组中的数字进行分类排序,使得负数都靠左端,正数都靠右端,0 在中部。
注意问题的特点是:负数区域和正数区域内并不要求有序。可以利用这个特点通过 1 次线性扫描就结束战斗!!
⭐️代码
#include<stdio.h>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
void sort3p(int* x, int len)
{
int p = 0;
int left = 0;
int right = len-1;
while(p<=right){
if(x[p]<0){ //小于零的数往左边移
int t = x[left];
x[left] = x[p];
x[p] = t;
left++;
p++;
}
else if(x[p]>0){ //大于零的数往最右边移
int t = x[right];
x[right] = x[p];
x[p] = t;
right--;
}
else{ //x[p]==0
p++;
}
for(int i=0;i<14;i++)
printf("%d,",x[i]);
puts("\n");
}
}
int main()
{
int a[14]={25,18,-2,0,16,-5,33,21,0,19,-16,25,-3,0};
sort3p(a,14);
for(int i=0;i<14;i++)
printf("%d,",a[i]);
return 0;
}
其中 x 指向待排序的整型数组,len 是数组的长度。
🍊🍊🍊
总结不易,看到这那就来个三连吧,肝。。。🍺🍺🍺
🍊🍊🍊
署名:左手の明天