第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,向左扫描使得差值最小,或者分别向中间扫描,去数组差值最小。

posted @ 2025-03-12 22:40  好好好好好好好好好  阅读(105)  评论(0)    收藏  举报