蓝桥杯题目的练习(c++)
1.时间显示
1思路是单位的换算,时间的取整,以及用余数来确定范围,1秒=1000毫秒
2.c++涉及两位数补零需用到这个库,在使用setw(n),setfill(‘x’),用x填充不足的n位数
3.有些题在调用这些库的时候,会导致时间超时,就得考虑使用c语言得格式化输出
cout <<setw(2)<<setfill('0') << hour
时间超时得例子
题目描述
给定一个t,将t秒转化为HH:MM:SS的形式,表示HH小时MM分钟SS秒。HH,MM,SS均是两位数,如果小于10用0补到两位。
输入
第一行一个数T(1< =T< =100,000),表示数据组数。后面每组数据读入一个数t,0< =t< 246060。
输出
每组数据一行,HH:MM:SS。
样例输入
2
0
86399
样例输出
00:00:00
23:59:59
#include<iostream>
#include<iomanip>
using namespace std;
int main()
{
int t;
cin >> t;
int* num = new int[t];
for (int i = 0; i < t; i++)
{
cin >> num[i];
}
for (int i = 0; i < t; i++)
{
int h = num[i] / 3600;
int m = (num[i] %3600) / 60;
int s = num[i] % 3600 % 60;
printf("%02d:%02d:%02d\n", h, m, s);
//在使用函数库时导致时间超时
//cout << setw(2) << setfill('0') << h << ":" << setw(2) << setfill('0')<< m << ":" << setw(2) << setfill('0') << s;
//cout << endl;
}
delete[]num;
return 0;
}
2.十六进制转化为八进制
*思路是十六进制转化为二进制,在转化为八进制
#include<iostream>
#include<string>
using namespace std;
void ChangeBin(string binnum)//二进制转化为八进制
{
//flage是第一个计算除为零时不输出
int eightnum,flage=0;
for (int i = 0; i < binnum.length(); i += 3)
{
eightnum = 4 * (binnum[i] - '0') + 2 * (binnum[i + 1] - '0') + 1 * (binnum[i + 2] - '0');
//判断第一次转化是否为零
if (eightnum)
{
flage = 1;
}
if(flage)
cout << eightnum;//转化一次输出一次
}
cout << endl;
}
int main()
{
//输入转变的个数
int n;
cin >> n;
string* hexnum = new string[n];
for (int i = 0; i < n; i++)
{
cin >> hexnum[i];
}
//把十六进制转化为二进制
for (int i = 0; i < n; i++)
{
string tem = hexnum[i];
string binnum = "";
for (int j = 0; j < tem.length(); j++)
{
switch (tem[j])
{
case '0':binnum += "0000"; break;
case '1':binnum += "0001"; break;
case '2':binnum += "0010"; break;
case '3':binnum += "0011"; break;
case '4':binnum += "0100"; break;
case '5':binnum += "0101"; break;
case '6':binnum += "0110"; break;
case '7':binnum += "0111"; break;
case '8':binnum += "1000"; break;
case '9':binnum += "1001"; break;
case 'A':binnum += "1010"; break;
case 'B':binnum += "1011"; break;
case 'C':binnum += "1100"; break;
case 'D':binnum += "1101"; break;
case 'E':binnum += "1110"; break;
case 'F':binnum += "1111"; break;
default:
break;
}
}
//因为转化为八进制时是每三个二进制为一个八进制数,所以不足的需要补齐
if (tem.length() % 3 == 1)
binnum = "00" + binnum;
if (tem.length() % 3 == 2)
binnum = "0" + binnum;
//二进制转化为八进制的函数
ChangeBin(binnum);
}
delete[]hexnum;
return 0;
}
3.十六进制转十进制
#include<iostream>
#include<string>
using namespace std;
void ChangeBin(string binnum)//二进制转化为八进制
{
int tem = 1;
int tennum = 0;
for (int i = binnum.length() - 1; i >= 0; i--)
{
tennum = tennum + (binnum[i]-'0') * tem;
tem = tem * 2;
}
cout << tennum;
cout << endl;
}
int main()
{
string tem;
cin >> tem;
string binnum = "";
for (int j = 0; j < tem.length(); j++)
{
switch (tem[j])
{
case '0':binnum += "0000"; break;
case '1':binnum += "0001"; break;
case '2':binnum += "0010"; break;
case '3':binnum += "0011"; break;
case '4':binnum += "0100"; break;
case '5':binnum += "0101"; break;
case '6':binnum += "0110"; break;
case '7':binnum += "0111"; break;
case '8':binnum += "1000"; break;
case '9':binnum += "1001"; break;
case 'A':binnum += "1010"; break;
case 'B':binnum += "1011"; break;
case 'C':binnum += "1100"; break;
case 'D':binnum += "1101"; break;
case 'E':binnum += "1110"; break;
case 'F':binnum += "1111"; break;
default:
break;
}
}
//二进制转化为十进制的函数
ChangeBin(binnum);
return 0;
}
4.十进制转化为十六进制
(1)
#include<iostream>
#include<string>
using namespace std;
int main()
{
long num;
cin >> num;
if (num == 0)
cout << 0;
string hex = "0123456789ABCDEF";
string hexnum = "";
while (num > 0)
{
int tem;
tem = num % 16;
hexnum = hexnum + hex[tem];
num = num / 16;
}
for (int i = hexnum.length() - 1; i >= 0; i--)
{
cout << hexnum[i];
}
return 0;
}
5.特殊回文数
解题思路:
1.通过循环把五位数,六位数的每一位保存在变量中
2.通过变量之间的位置关系判断是否为回文
3.变量之间的和是否与n相等
#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main()
{
int m;
cin >> m;
//五位数
for (long n = 10000; n < 100000; n++)
{
//把六位数遍历出来
int first = n / 10000;
int second = (n - first * 10000) / 1000;
int third = (n - first * 10000 - second * 1000) / 100;
int four = (n - first * 10000 - second * 1000 - third * 100) / 10;
int five = (n - first * 10000 - second * 1000 - third * 100) % 10;
//判断是否符合回文数
if (first == five && second == four)
{
//判断是否满足m
if ((first + second + third + four + five) == m)
cout << n << endl;
}
}
//六位数
for (long n = 100000; n < 1000000; n++)
{
int first = n / 100000;
int second = (n - first * 100000) / 10000;
int third = (n - first * 100000 - second * 10000) / 1000;
int four = (n - first * 100000 - second * 10000 - third * 1000) / 100;
int five = (n - first * 100000 - second * 10000 - third * 1000 - four * 100)/10;
int six= (n - first * 100000 - second * 10000 - third * 1000 - four * 100-five*10);
if (first == six && second == five && third==four)
{
if ((first + second + third + four + five+six) == m)
cout << n << endl;
}
}
return 0;
}
6.杨辉三角
解题思路:
1.利用杨辉三角中的两个性质(1)每个数等于它上方两数之和。
(2)每行数字左右对称,由1开始逐渐变大
2.利用二位数组的方式。图片来源:https://www.cnblogs.com/yyxayz/p/4556831.html
注意事项:此次的的二位数组需要动态申请,注意二维数组动态申请与释放的方式
#include<iostream>
#include<string>
using namespace std;
int main()
{
int n;
cin >> n;
//动态申请二维数组
int** a = new int* [n];
for (int i = 0; i < n; i++)
{
a[i] = new int[n];
}
//初始化1
for (int i = 0; i < n; i++)
{
a[i][0] = 1;
a[i][i] = 1;
}
//循环相加
for (int i = 2; i < n; i++)
{
for (int j = 1; j < i ; j++)
{
a[i][j] = a[i - 1][j - 1] + a[i - 1][j];
}
}
//输出
for (int i = 0; i < n; i++)
{
for (int j = 0; j <= i; j++)
{
cout << a[i][j] << " ";
}
cout << endl;
}
//动态销毁二维数组
for (int i = 0; i < n; i++)
{
delete a[i];
}
delete a;
return 0;
}
7.字符图形
解题思路:
1.利用字符串的ASCII码
2.先计算前面部分,在计算后面一部分
备注:最终只通过70%,也不知道原因出在哪里
#include<iostream>
#include<string>
using namespace std;
int main()
{
int rows, clums;
cin >> rows >> clums;
int start = 65;
for (int i = 0; i < rows; i++)
{
for (int k = i; k > 0; k--)
{
cout << (char)(start + k);
}
for (int j =0; j < clums-i;j++)
{
cout << (char)(start + j);
}
cout << endl;
}
return 0;
}
8.01字串
解题思路:
1.用栈把十进制转化为二进制
2.通过判断栈的大小把位数补齐
注意事项:
1.使用栈引用#include这个库
#include<iostream>
#include<string>
#include<stack>
#include<iomanip>
using namespace std;
void DemChangeBin(stack<int>& tem, int demical)//把十进制转化为二进制并存入栈中
{
do
{
int k = demical % 2;
tem.push(k);
demical = demical / 2;
} while (demical>0);
}
int main()
{
for (int i = 0; i < 32; i++)
{
stack<int>tem;
DemChangeBin(tem, i);
int n = tem.size();
//入过栈的位数不够5位,补齐0
for (int k = 0; k < 5 - n; k++)
cout << 0;
//把栈中的数输出
for (int j = 0; j < n; j++)
{
cout << tem.top();
tem.pop();
}
cout <<endl;
}
return 0;
}
9.Fibonacci数列
解题思路:
1使用递归算法:但是时间太长不能通过检测
2用栈来替代递归算法
递归算法
#include<iostream>
#include<string>
using namespace std;
int FibonacciSum(int n)
{
if (n == 1 || n == 2)
return 1;
else
{
return FibonacciSum(n - 1) + FibonacciSum(n - 2);
}
}
int main()
{
int n;
cin >> n;
int tem= FibonacciSum(n);
cout << tem % 10007;
return 0;
}
非递归算法(循环与栈的结合)
#include<iostream>
#include<string>
#include<stack>
using namespace std;
int main()
{
int n;
cin >> n;
//先判断数据范围
if (n <= 2)
cout << 1;
else
{
int n1, n2;
stack<int>tem;
n1 = n2 = 1;
//栈最开始有两个数据
tem.push(n1);
tem.push(n2);
int sum = 0;
for (int i = 0; i < n - 2; i++)
{//n需要-2
int x2 = tem.top();
tem.pop();
int x1 = tem.top();
tem.pop();
//先让两个数据出栈
sum = (x1 + x2) % 10007;
//余数的性质,中间取余与最后结果取余一样
tem.push(x2);
tem.push(sum);
}
cout << sum;
}
return 0;
}
10.圆的面积
1.关键是小数点后面位置的精确,需要调用函数库#include
2.让后使用cout<<setprecision(n)<<fixed<<area (其中n是精确的位数,fixed是不满位数自动补零,area是要输出的数)
#include<iostream>
#include<string>
#include<iomanip>
using namespace std;
int main()
{
double PI = 3.14159265358979323;
int r;
cin >> r;
double area = r * r * PI;
cout << setprecision(7) << fixed << area;
return 0;
}
11.印章
解题思路:参考连接:https://blog.csdn.net/okok__TXF/article/details/121099645#comments_20096539
#include<iostream>
#include<string>
#include<iomanip>
#include<math.h>
using namespace std;
double a[25][25],p;
int main()
{
int n, m;
cin >> n >> m;
p = 1.0 / n;//每种出现的概率
for (int i = 1; i <= m; ++i)
{
for (int j = 1; j <= n; ++j)
{
if (i < j)
a[i][j] = 0;
if (j == 1)
a[i][j] =pow(p,i-1);
else
a[i][j] = a[i - 1][j] * (j*1.0 / n) + a[i - 1][j - 1] * ((n - j + 1)*1.0 / n);
}
}
cout <<setprecision(4)<<fixed<< a[m][n];
return 0;
}
12拿金币
**解题思路:
1.因为只能往下,和往右走,所以第一例的数据只可能来自于上一个,第一行的数据就只能来自于左边
2.除了第一例和第一行的数据,其他数据都来源于左一个和上一个数据
注意: (1)涉及到二维数组的动态申请和消除
**
#include<iostream>
#include<string>
#include<iomanip>
#include<math.h>
using namespace std;
int main()
{
int n;
cin >> n;
//申请二维数组
int** sum = new int* [n];
for (int i = 0; i < n; i++)
{
sum[i]= new int[n];
}
for (int i = 0; i < n; i++)
{
for (int j = 0; j < n; j++)
{
cin >> sum[i][j];
}
}
//初始化第一行和第一列
for (int i = 1; i < n; i++)
{
sum[i][0] = sum[i][0] + sum[i - 1][0];
}
for (int j = 1; j < n; j++)
{
sum[0][j] = sum[0][j] + sum[0][j-1];
}
//初始化其他的数据
for (int i = 1; i < n; i++)
{
for (int j = 1; j < n; j++)
{
int tem = max(sum[i][j - 1], sum[i - 1][j]);
sum[i][j] = tem + sum[i][j];
}
}
//求取最大值
int maxnum = sum[0][0];
for (int i = 1; i < n; i++)
{
for (int j = 1; j < n; j++)
{
if (sum[i][j] > maxnum)
maxnum = sum[i][j];
}
}
//输出
cout << maxnum;
//动态销毁二维数组
for (int i = 0; i < n; i++)
{
delete[] sum[i];
}
delete[]sum;
return 0;
}
13.数字游戏
问题描述
给定一个1~N的排列a[i],每次将相邻两个数相加,得到新序列,再对新序列重复这样的操作,显然每次得到的序列都比上一次的序列长度少1,最终只剩一个数字。
例如:
3 1 2 4
4 3 6
7 9
16
现在如果知道N和最后得到的数字sum,请求出最初序列a[i],为1~N的一个排列。若有多种答案,则输出字典序最小的那一个。数据保证有解。
输入格式
第1行为两个正整数n,sum
输出格式
一个1~N的一个排列
样例输入
4 16
样例输出
3 1 2 4
数据规模和约定
0<n<=10
解题思路
1.知识点:全排序
2.用到C++函数库,next_premutatiom()具体使用
3.注意数组的变化
#include<iostream>
#include<string>
#include<iomanip>
#include<math.h>
#include<algorithm>
using namespace std;
//计算该排列最终得到的数据
int Addsum(int a[],int n)
{
for (int i = n; i > 0; i--)
{
for (int j = 0; j < i - 1; j++)
a[j] = a[j] + a[j + 1];
}
return a[0];
}
int main()
{
int n, sum;
cin >> n >> sum;
int* a = new int[n];
int* b = new int[n];
//生成升序的初始排列
for (int i = 1; i <= n; i++)
{
a[i - 1] = i;
}
//用函数对每个全排列进行判断
do
{
//拷贝一份该排列
for (int i = 0; i < n; i++)
{
b[i] = a[i];
}
//判断该排列是否满足要求,满足则输出
if (sum == Addsum(b, n))
{
for (int i = 0; i < n; i++)
{
cout << a[i] << " ";
}
break;
}
} while (next_permutation(a,a+n));
delete[] a;
delete[] b;
return 0;
}