蓝桥杯B组c/c++题解
试题A 空间
问题描述
小蓝准备用256B的内存空间开一个数组,数组的每个元素都是32位二进制整数,如果不考虑程序占用空间和维护内存需要的辅助空间,请问256MB的空间可以存储多少个32位二进制数
#include<iostream>
using namespace std;
int main()
{
cout << 256 * 1024 * 1024 * 8 / 32 << endl;
return 0;
}
试题B 卡片
问题描述
小蓝有很多数字卡片,每张卡片上都是数字0到9。
小蓝准备用这些卡片来拼一些数,他想从1开始拼出正整数,每拼一个,就保存起来,卡片就不能用来拼其它数了。
小蓝想知道自己能从1拼到多少。
例如,当小蓝有30张卡片,其中0到9各3张,则小蓝可以拼出1到10,但是拼11时卡片1已经只有一张了,不够拼出11。
现在小蓝手里有0到9的卡片各2021张,共20210张,请问小蓝可以从1.拼到多少?
#include<iostream>
using namespace std;
int a[10],flag = 0;
int main()
{
for(int i = 1;;i++)
{
int r = i;
while(r)
{
if(++a[r%10] > 2021)
{
cout << i - 1;
flag++;
break;
}
r/= 10;
}
if(flag) break;
}
return 0;
}
试题C 直线
问题描述
在平面直角坐标系中,两点可以确定一条直线。 如果有多点在一条直线上,那么这些点中任意两点确定的直线是同一条。
给定平面上2x3个整点(x,y)0≤x<2,0≤y<3x∈Z,y∈Z),即横坐标是0到1(包含0和1)之间的整数、纵坐标是0到2 (包含0和2)之间的整数的点。这些点-一共确定了11条不同的直线。
给定平面上20x21个整点(xy)I0sx<20.0≤y<21.x∈Z.y∈Z),即横坐标是0到19(包含0和19)之间的整数、纵坐标是0到20(包含0和20)之间的整数的点。请问这些点一共确定 了多少条不同的直线。
提示
由于c和c++的浮点型存在误差,所以我们只需让两个浮点型的差值小于1e-8则可判定两浮点数相等.
#include<bits/stdc++.h>
using namespace std;
const int N = 2*1e5 + 10;
typedef struct
{
double k;
double b;
}Int;
Int arr[N];
bool cmp(Int a,Int c)
{
if(a.k != c.k) return a.k < c.k;
return a.b <= c.b;
}
int main()
{
int flag = 0;
for(int x1 = 0;x1 < 20;x1++)
{
for(int y1 = 0;y1 < 21;y1++)
{
for(int x2 = 0;x2 < 20;x2++)
{
for(int y2 = 0;y2 < 21;y2++)
{
if(x1 != x2)
{
arr[flag].k = (double)(y2-y1)/(x2-x1);
arr[flag++].b = y1 - arr[flag].k * x1;
}
}
}
}
}
sort(arr,arr + flag,cmp);
int num = 1;
for(int i = 1;i < flag;i++)
{
if(!(fabs(arr[i].k - arr[i-1].k) < 1e-8) || !(fabs(arr[i].b - arr[i-1].b) < 1e-8)) num++;
}
cout << num + 20 << endl;
return 0;
}
试题D 货物摆放
题目描述
小蓝有一个超大的仓库,可以摆放很多货物。
现在,小蓝有n箱货物要摆放在仓库,每箱货物都是规则的正方体。小蓝规定了长、宽、高三个互相重直的方向,每箱货物的边都必须严格平行于长、宽、高。
小监希望所有的货物最终摆成一个大的立方体。即在长、宽、高的方向上分别堆L、w. H的货物,满足n=LxWxH。
给定n,请问有多少种堆放货物的方案满足要求。
例如,当n=4时,有以下6种方案: 1x1x4. 1x2x2、 1x4x1. 2x1x2、
请问,当n= 2021041820210418 (注意有 16位数字)时,总共有多少种方案?
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int main()
{
ll n;
cin >> n;
vector<ll> a;
for(ll i = 1;i*i <= n;i++)
{
if(n % i == 0)
{
a.push_back(i);
if(n/i != i) a.push_back(n/i);
}
}
int num = 0;
for(auto b: a)
for(auto c:a)
for(auto d:a)
if(b*c*d == n)
num++;
cout << num << endl;
return 0;
}
试题E 路径
题目描述
小蓝学习了最短路径之后特别高兴,他定义了-个特别的图,希望找到图中的最短路径。
小蓝的图由2021个结点组成,依次编号1至2021.
对于两个不同的结点a,b,如果a和b的差的绝对值大于21,则两个结点之间没有边相连:如果a和b的差的绝对值小于等于21,则两个点之间有-条长度为a和b的最小公倍数的无向边相连。
例如:结点1和结点23之间没有边相连:结点3和结点24之间有一-条无向边,长度为24:结点15和结点25之间有一 条无向边,长度为75。
请计算,结点1和结点2021之间的最短路径长度是多少。
试题F 时间显示
题目描述
小蓝要和朋友合作开发一个时间显示的网站。
在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从 1970 年 月 日 00:00:00 到当前时刻经过的毫秒数。
现在,小蓝要在客户端显示出这个时间。
小蓝不用显示出年月日,只需要显示出时分秒即可,毫秒也不用显示,直接舍去即可。
给定一个用整数表示的时间,请将这个时间对应的时分秒输出。
输入
输入一行包含一个整数,表示时间。
对于所有评测用例,给定的时间为不超过 10^18 的正整数。
输出
输出时分秒表示的当前时间,格式形如 HH:MM:SS,其中 HH 表示时,值为 0 到 ,MM 表示分,值为 到 ,SS 表示秒,值为 到 。
时、分、秒不足两位时补前导 。
样例
46800999
13:00:00
代码如下
#include<iostream>
using namespace std;
int main()
{
long long n,mm,hh,ss;
cin >>n;
hh = n /(60*60*1000);
n -= hh * 60 * 60*1000;
mm = n/(60*1000);
n -= mm * 60 * 1000;
ss = n / 1000;
printf("%02d:%02d:%02d\n",hh%24,mm,ss);
return 0;
}
试题G 砝码称重
题目描述
你有一架天平和 N 个砝码,这 N 个砝码重量依次是 W1,W2,⋅⋅⋅,WN.
请你计算一共可以称出多少种不同的正整数重量?
注意砝码可以放在天平两边。
输入
输入的第一行包含一个整数 N。
第二行包含 个整数:W1,W2,W3,⋅⋅⋅,WN。
对于 50%50% 的评测用例,1≤N≤15。
对于所有评测用例,1≤N≤100,N 个砝码总重不超过 10^5
输出
输出一个整数代表答案。
样例
3
1 4 6
10
提示
能称出的 10 种重量是:1、2、3、4、5、6、7、9、10、11。
1 = 1
2 = 6 − 4 (天平一边放 6,另一边放 4)
3 = 4 − 1
4 = 4
5 = 6 − 1
6 = 6
7 = 1 + 6
9 = 4 + 6 − 1
10 = 4 + 6
11 = 1 + 4 + 6
此题是dp题,可参考acwing闫氏dp分析法
每个次添加砝码时需要考虑是加上这个砝码的重量还是减去这个砝码重量或者是不放这块砝码.
代码如下
#include<bits/stdc++.h>
using namespace std;
const int N = 110,M = 1e5 + 10;
bool dp[N][M];
int a[N],sum = 0,num = 0;
int main()
{
int n;
cin >> n;
for(int i = 1;i <= n;i++)
{
cin >> a[i];
sum += a[i];
}
dp[0][0] = true;
for(int i = 1;i <= n;i++)
{
for(int j = 0;j <= sum;j++)
{
dp[i][j] = dp[i-1][j] || dp[i-1][j + a[i]] || dp[i-1][abs(j - a[i])];
}
}
for(int j = 0;j <= sum;j++)
{
if(dp[n][j]) num++;
}
cout << num - 1<< endl;
return 0;
}
试题H 杨辉三角
题目描述
下面的图形是著名的杨辉三角形:
如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:
1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, …
给定一个正整数 N,请你输出数列中第一次出现 N 是在第几个数?
输入
输入一个整数 N。
对于 20% 的评测用例,1≤N≤10;
对于所有评测用例,1≤N≤109。
输出
输出一个整数代表答案。
样例
6
13
提示
此题我们只需关注杨辉三角的左侧,因为杨辉三角 是对称的,如果右侧出现则左侧必定出现 ,且出现较早.而且我们采用斜视法,一斜行一斜行得看,根据数据范围最高到达第16行.
代码如下
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
int n;
ll C (int a,int b)
{
ll num = 1;
for(int i = a,j = 1;j <= b;i-- ,j++)
{
num = num * i / j;
if(num > n) return num;
}
return num;
}
bool check(int k)
{
ll l = 2*k,r = max((ll)n, l);
while(l < r)
{
ll mid = l + r >> 1;
if(C(mid,k) >= n) r = mid;
else l = mid + 1;
}
if(C(r,k) != n) return false;
cout << r * (r + 1)/2 + k + 1 <<endl;
return true;
}
int main()
{
cin >> n;
for(int i = 16;;i --)
{
if(check(i)) break;
}
return 0;
}