第2015届蓝桥杯真题
试题 A: 握手问题
| 试题 A: 握手问题 本题总分:5 分 | |
|---|---|
| 问题描述 | 小蓝组织了一场算法交流会议,总共有 50 人参加了本次会议在会议上,大家进行了握手交流。按照惯例他们每个人都要与除自己以外的其他所有人进行一次握手(且仅有一次)。但有 7 个人,这 7 人彼此之间没有进行握手(但这 7 人与除这 7 人以外的所有人进行了握手)。请问这些人之间一共进行了多少次握手?注意 A 和 B 握手的同时也意味着 B 和 A 握手了,所以算作是一次握手。 |
| 答案提交 | 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个整数,在提交答案时只填写这个整数,填写多余的内容将无法得分。 |
点击查看代码
#include <iostream>
using namespace std;
int stu()
{
int a=0;
for(int i=49;i>=7;--i)
{
a+=i;
}
return a;
}
int main()
{
cout<<stu();
return 0;
}
思路:
这个问题可以用组合数学的知识来解决。
首先,总共有 50 个人,每个人要与除自己以外的其他所有人进行一次握手,那么总的握手次数为 (502)(250)。
但是有 7 个人彼此之间没有进行握手,这意味着这 7 个人之间本应该进行 (72)(27) 次握手,但是实际上没有进行握手。
所以最终的握手次数为 (502)−(72)(250)−(27)。
计算结果为:
(502)−(72)=50×492−7×62=1225−21=1204(250)−(27)=250×49−27×6=1225−21=1204
所以最终答案为 1204。
试题C:好数
| 描述 | 试题 C: 好数 时间限制: 1.0s 内存限制: 256.0MB 本题总分:10 分 |
|---|---|
| 问题描述 | 一个整数如果按从低位到高位的顺序,奇数位(个位、百位、万位 · · · )上的数字是奇数,偶数位(十位、千位、十万位 · · · )上的数字是偶数,我们就称之 为“好数”。给定一个正整数 N,请计算从 1 到 N 一共有多少个好数。 |
| 输入格式 | 一个整数 N。 |
| 输出格式 | 一个整数代表答案。 |
| 输入样例1 | 24 |
| 输出样例1 | 7 |
| 输入样例2 | 2024 |
| 输出样例2 | 150 |
| 样例说明 | 对于第一个样例,24 以内的好数有 1、3、5、7、9、21、23,一共 7 个。 |
| 评测样例规模与约定 | 对于 10% 的评测用例,1 ≤ N ≤ 100。对于 100% 的评测用例,1 ≤ N ≤ 1e7。 |
点击查看代码
#include <iostream>
#include<string.h>
using namespace std;
int stu()
{
int a,q=0;
cin>>a;
int b[9];
for(int i=1;i<a;i++)
{
int sign=0,l=0;
int k=i;
while(k)
{
b[l]=k%10;
l++;
k/=10;
}
for(int j=0;j<l;j++)
{
if(j%2==0)
{
if(b[j]%2==0) sign=1;
}
else{
if(b[j]%2==1) sign=1;
}
}
if(sign==0) q++;
}
return q;
}
int main()
{
cout<<stu();
return 0;
}
思路:
思路是从 1 开始遍历到 n,对每个数字进行判断是否为好数。在判断是否为好数时,它使用了一个变量 q 来表示当前数字是否为好数,并在遍历数字的每一位时进行更新。具体来说,它遍历了每个数字的每一位,如果相邻位上的数字奇偶性相同(即相邻位都是奇数或者都是偶数),则将 q 设置为 0,表示当前数字是好数,否则将 q 设置为 1,表示当前数字不是好数。最后统计所有好数的数量q并返回。
试题B:小球反弹
| 问题 | 试题 B: 小球反弹 本题总分:5 分 |
|---|---|
| 问题描述 | 有一长方形,长为 343720 单位长度,宽为 233333 单位长度。在其内部左上角顶点有一小球(无视其体积),其初速度如图所示且保持运动速率不变,分解到长宽两个方向上的速率之比为 dx : dy = 15 : 17。 |
| 答案提交 | 这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一个小数,在提交答案时只填写这个小数,填写多余的内容将无法得分。 |
点击查看代码
#include <bits/stdc++.h>
using namespace std;
bool isInt(double num)
{
return fabs(num - (int)num) < 1e-6;
}
int main()
{
int l = 343720, w = 233333, dx = 15, dy = 17, i = 1;
double dl, dw, result;
dl = l * 2, dw = dl / 15 * 17;
while (true)
{
if (isInt(dw * i / w / 2))
{
break;
}
i++;
}
result = dl / dx * sqrt(dx * dx + dy * dy) * i;
printf("%.2lf", result);
return 0;
}
思路:
小球在长宽固定的区域内弹射,每当小球横向移动15n,其纵向必定移动17n
小球横向移动一个来回就是2倍长度,纵向移动距离是横向移动距离的17/15倍
小球横向每移动一个来回,x坐标都会移动到起点,纵向若此时也移动了宽度的若干个来回,说明小球到达起点。
问题D:R格式
| 问题 | 试题 D: R 格式 时间限制: 1.0s 内存限制: 256.0MB 本题总分:10 分 |
|---|---|
| 问题描述 | 小蓝最近在研究一种浮点数的表示方法:R 格式。对于一个大于 0 的浮点数 d,可以用 R 格式的整数来表示。给定一个转换参数 n,将浮点数转换为 R 格式整数的做法是:1. 将浮点数乘以 2^n;2. 四舍五入到最接近的整数。 |
| 输入格式 | 一行输入一个整数 n 和一个浮点数 d,分别表示转换参数,和待转换的浮点数。 |
| 输出格式 | 输出一行表示答案:d 用 R 格式表示出来的值。 |
| 样例输入 | 2 3.14 |
| 样例输出 | 13 |
| 样例说明 | 3.14 × 2^2 = 12.56,四舍五入后为 13。 |
| 评测用例规模与约定 | 对于 50% 的评测用例:1 ≤ n ≤ 10,1 ≤ 将 d 视为字符串时的长度 ≤ 15。对于 100% 的评测用例:1 ≤ n ≤ 1000,1 ≤ 将 d 视为字符串时的长度 ≤ 1024;保证 d 是小数,即包含小数点。 |
点击查看代码
#include<bits/stdc++.h>
using namespace std;
string d;
int n, arr[200000] = { 0 }, pos = 0, len;
int main()
{
cin >> n >> d;
reverse(d.begin(), d.end());
pos = d.find('.');
d.erase(pos, 1);
len = d.size();
for (int i = 0; i < len; i++)
arr[i] = d[i] - '0';
while (n--) {
for (int i = 0; i < len; i++) {
arr[i] = arr[i] * 2;
}
for (int i = 0; i < len; i++) {
if (arr[i] > 9) {
arr[i + 1] += arr[i] / 10;
arr[i] %= 10;
}
if (arr[len])
len++;
}
}
if (arr[pos - 1] > 4) {
arr[pos] += 1;
for (int i = pos; i < len; i++) {
if (arr[i] > 9) {
arr[i + 1] += arr[i] / 10;
arr[i] %= 10;
}
if (arr[len])
len++;
}
}
for (int i = len - 1; i >= pos; i--)
cout << arr[i];
return 0;
}
思路:
由于数据太大,使用高精度计算记录小数点的位置然后删掉小数点,方便后边的存储将浮点数的每一位存在数组中,内层循环对每一位乘以2,然后判断进位,保留个位,将其余位向前进位;然后判断数组的长度是否变化外层循环控制该过程进行n次接下来四舍五入,然后判断是否有进位最后从后向前输出结果
问题E:宝石组合
| 描述 | 试题 E: 宝石组合 时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分 |
|---|---|
| 问题描述 | 在一个神秘的森林里,住着一个小精灵名叫小蓝。有一天,他偶然发现了一个隐藏在树洞里的宝藏,里面装满了闪烁着美丽光芒的宝石。这些宝石都有着不同的颜色和形状,但最引人注目的是它们各自独特的 “闪亮度” 属性。每颗宝石都有一个与生俱来的特殊能力,可以发出不同强度的闪光。小蓝共找到了 N 枚宝石,第 i 枚宝石的 “闪亮度” 属性值为 Hi,小蓝将会从这 N 枚宝石中选出三枚进行组合,组合之后的精美程度 S 可以用以下公式来衡量:image-20240413141707907其中 LCM 表示的是最小公倍数函数。小蓝想要使得三枚宝石组合后的精美程度 S 尽可能的高,请你帮他找出精美程度最高的方案。如果存在多个方案 S 值相同,优先选择按照 H 值升序排列后字典序最小的方案。 |
| 输入格式 | 第一行包含一个整数 N 表示宝石个数。第二行包含 N 个整数表示 N 个宝石的 “闪亮度”。 |
| 输出格式 | 输出一行包含三个整数表示满足条件的三枚宝石的 “闪亮度”。 |
| 输入样例 | 5 1 2 3 4 9 |
| 输出样例 | 1 2 3 |
| 评测用例规模与约定 | 对于 30% 的评测用例:3 ≤ N ≤ 100,1 ≤ Hi ≤ 1000。对于 60% 的评测用例:3 ≤ N ≤ 2000。对于 100% 的评测用例:3 ≤ N ≤ 10^5,1 ≤ Hi ≤ 10^5。 |
点击查看代码
#include <bits/stdc++.h>
using namespace std;
#define int long long
int gcd(int a, int b)
{
if (b == 0)
return a;
return gcd(b, a % b);
}
int lcm(int a, int b)
{
return a * b / gcd(a, b);
}
int gcd3(int a, int b, int c)
{
return gcd(gcd(a, b), c);
}
int lcm3(int a, int b, int c)
{
return lcm(lcm(a, b), c);
}
signed main()
{
int n;
cin >> n;
vector<int> a(n), b(3);
for (int i = 0; i < n; i++)
cin >> a[i];
sort(a.begin(), a.end());
int ans = 0;
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
for (int k = j + 1; k < n; k++)
{
int s = a[i] * a[j] * a[k] * lcm3(a[i], a[j], a[k]) / (lcm(a[i], a[j]) * lcm(a[i], a[k]) * lcm(a[j], a[k]));
if (s > ans)
{
ans = s;
b[0] = a[i];
b[1] = a[j];
b[2] = a[k];
}
}
}
}
cout << b[0] << " " << b[1] << " " << b[2];
return 0;
}
思路:
先进行排序,再找到值最大的符合条件的三个数,直接进行暴力求值
点击查看代码
#include <iostream>
using namespace std;
const int h=1e5;
int main()
{
int n,m[h+1]={},t,max=0;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>t;
m[t]++;
if(t>max) max=t;
}
for(int i=max;i>=1;i--)
{
int ans=0,cnt=0,num[3];
for(int j=i;j<=max;j+=i)
{
ans+=m[j];
for(int k=0;k<m[j]&&cnt<3;k++)
num[cnt++]=j;
if(ans>=3){
cout<<num[0]<<" "<<num[1]<<" "<<num[2];
return 0;
}
}
}
return 0;
}
思路:
由于数据量达到10⁵,所以暴力遍历不可取
寻找abc满足S最大,
反过来想,就是寻找S,存在abc
S=gcd(a,b,c),说明abc都是S的倍数
假定S为某个值,凑出3个倍数a,b,c
问题H:拔河
| 描述 | 试题 H: 拔河 时间限制: 1.0s 内存限制: 256.0MB 本题总分:20 分 |
|---|---|
| 问题描述 | 小明是学校里的一名老师,他带的班级共有 n 名同学,第i名同学力量值为 ai在闲暇之余,小明决定在班级里组织一场拔河比赛。为了保证比赛的双方实力尽可能相近,需要在这 nn名同学中挑选出两个队伍,队伍内的同学编号连续:两个队伍的人数不必相同,但是需要让队伍内的同学们的力量值之和尽可能相近。请计算出力量值之和差距最小的挑选队伍的方式。 |
| 输入格式 | 输入共两行。第一行为一个正整数 n。第二行为 n 个正整数 |
| 输出格式 | 输出共一行,一个非负整数,表示两个队伍力量值之和的最小差距。 |
| 样例输入 | 5 10 9 8 12 14 |
| 样例输出 | 1 |
| 评测用例规模与约定 | 对于 20% 的评测用例,保证 n ≤ 50。对于 100% 的评测用例,保证 n ≤ 10^3,ai ≤ 10^9。 |
点击查看代码
#include <iostream>
#include<cstring>
#include<math.h>
using namespace std;
typedef long long LL;
const int N=1e3+10;
int n;
int a[N];
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>a[i];
}
LL res=1e9;
for (int i = 1; i <= n; ++ i )
for (int j = i + 1; j <= n; ++ j )
{
int l = i - 1, r = j + 1;
LL sl = a[i], sr = a[j];
res = min(res, abs(sr - sl));
while (l >= 1 && r <= n)
{
if (sl > sr)
sr += a[r ++];
else
sl += a[l --];
res = min(res, abs(sr - sl));
}
while (l >= 1)
{
sl += a[l --];
res = min(res, abs(sr - sl));
}
while (r <= n)
{
sr += a[r ++];
res = min(res, abs(sr - sl));
}
}
cout<<res<<endl;
return 0;
}
思路:
通过枚举r1,l2,用双指针i,j,分别从r1,l2,向左扫描使得差值最小,或者分别向中间扫描,去数组差值最小。

浙公网安备 33010602011771号