第八届A组蓝桥杯决赛

本文汇总了历年蓝桥杯决赛题目,包含平方十位数、生命游戏、表达式计算等题目。涉及平方数查找、细胞自动机规则应用、四则混合运算式解析等内容,还给出部分题目的答案及解题思路链接,如二分法解析区间移位题目。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

历年蓝桥杯决赛题目汇总?

1、标题:平方十位数

由0~9这10个数字不重复、不遗漏,可以组成很多10位数字。
这其中也有很多恰好是平方数(是某个数的平方)。

比如:1026753849,就是其中最小的一个平方数。

请你找出其中最大的一个平方数是多少?

注意:你需要提交的是一个10位数字,不要填写任何多余内容。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

bool is(ll n){//判断是否是平方数 
	ll q=sqrt(n);
	if(q*q==n){
		return true;
	}
	return false;
}
bool chong (ll n){//判断十位数字有无重复 
	int arr[10];
	int k=0;
	while(n){
		arr[k++]=n%10;
		n/=10;
	}
	for(int i=0;i<10;i++){
		for(int j=i+1;j<10;j++){
			if(arr[i]==arr[j])
				return false;
		}
	}
	return true;
} 
int main(){
	for(ll i=9876543210;i>1026753849;i--){
		if(is(i)&&chong(i)){
			cout<<i<<endl;
			break;
		}
	}
	return 0;
}


答案:9814072356

2、


标题:生命游戏

康威生命游戏是英国数学家约翰·何顿·康威在1970年发明的细胞自动机。  
这个游戏在一个无限大的2D网格上进行。

初始时,每个小方格中居住着一个活着或死了的细胞。
下一时刻每个细胞的状态都由它周围八个格子的细胞状态决定。

具体来说:

1. 当前细胞为存活状态时,当周围低于2个(不包含2个)存活细胞时,

 该细胞变成死亡状态。(模拟生命数量稀少)

2. 当前细胞为存活状态时,当周围有2个或3个存活细胞时,

 该细胞保持原样。

3. 当前细胞为存活状态时,当周围有3个以上的存活细胞时,

该细胞变成死亡状态。(模拟生命数量过多)

4. 当前细胞为死亡状态时,当周围有3个存活细胞时,

该细胞变成存活状态。 (模拟繁殖)

当前代所有细胞同时被以上规则处理后, 可以得到下一代细胞图。

按规则继续处理这一代的细胞图,可以得到再下一代的细胞图,周而复始。

例如假设初始是:(X代表活细胞,.代表死细胞)
.....
.....
.XXX.
.....

下一代会变为:
.....
..X..
..X..
..X..
.....

康威生命游戏中会出现一些有趣的模式。例如稳定不变的模式:

....
.XX.
.XX.
....

还有会循环的模式:

......      ......       ......
.XX...      .XX...       .XX...
.XX...      .X....       .XX...
...XX.   -> ....X.  ->   ...XX.
...XX.      ...XX.       ...XX.
......      ......       ......


本题中我们要讨论的是一个非常特殊的模式,被称作"Gosper glider gun":

......................................
.........................X............
.......................X.X............
.............XX......XX............XX.
............X...X....XX............XX.
.XX........X.....X...XX...............
.XX........X...X.XX....X.X............
...........X.....X.......X............
............X...X.....................
.............XX.......................
......................................

假设以上初始状态是第0代,请问第1000000000(十亿)

代一共有多少活着的细胞?

注意:我们假定细胞机在无限的2D网格上推演,

并非只有题目中画出的那点空间。

当然,对于遥远的位置,其初始状态一概为死细胞。

注意:需要提交的是一个整数,不要填写多余内容。

这道题目不会做,看了大佬的思路,能理解。

https://blog.youkuaiyun.com/TQCAI666/article/details/80325524

3、标题:表达式计算

虽然我们学了许久的程序设计,但对于简单的四则混合运算式,

如果让我们完全白手起家地编程来解析,还是有点棘手。

这里,我们简化一下问题,假设只有加法和乘法,并且没有括号来改变优先级。

再假设参加运算的都是正整数。

在这么多的限制条件下,表达式的解析似乎简单了许多。

下面的代码解决了这个问题。请仔细阅读源码,并填写划线部分缺少的代码。


#include <stdio.h>

int f3(const char* s, int begin, int end)
{
    int sum = 0;
    int i;
    for(i=begin; i<end; i++){
        if(s[i]==' ') continue;
        sum = sum * 10 + (s[i]-'0');
    }
    return sum;
}

int f2(const char* s, int begin, int end)
{
    int p = begin;
    int pro = 1;
    while(1){
        int p0 = p;
        while(p!=end && s[p]!='*') p++;
        pro *= _______________________________;  //填空
        if(p==end) break;
        p++;
    }
    printf("f2: pro=%d\n", pro);
    return pro;
}

int f(const char* s)
{
    int p = 0;
    int sum = 0;
    while(1){
        int p0 = p;
        while(s[p]!=0 && s[p]!='+') p++;
        sum += f2(s,p0,p);
        if(s[p]==0) break;
        p++;
    }
    
    return sum;
}

int main()
{
    int x = f("12+18+5*4*3+10");
    printf("%d\n", x);
    return 0;
}

注意:只填写划线处缺少的内容,不要填写已有的代码或符号,也不要填写任何解释说明文字等。

#include <stdio.h>
#include<bits/stdc++.h>
using namespace std;
int f3(const char* s, int begin, int end)
{
	int sum = 0;
	int i;
	for(i=begin; i<end; i++){
		if(s[i]==' ') continue;
		sum = sum * 10 + (s[i]-'0');
	}
	return sum;
}
// 12+18+5*4*3+10 , 0 , 2
int f2(const char* s, int begin, int end)
{
	int p = begin;
	int pro = 1;
	while(1){
		int p0 = p;
		while(p!=end && s[p]!='*') p++; 
		pro *= f3(s,p0,p);  //填空
		if(p==end) break; 
		p++;
	}
	printf("f2: pro=%d\n", pro);
	return pro;
}

int f(const char* s)
{
	int p = 0;
	int sum = 0;
	while(1){
		int p0 = p;
		while(s[p]!=0 && s[p]!='+') p++; 
		sum += f2(s,p0,p);
		if(s[p]==0) break;
		p++;
	}
	
	return sum;
}

int main()
{
	int x = f("12+18+5*4*3+10");//结果为100
	printf("%d\n", x);
	return 0;
}

答案:f3(s,p0,p);

4、标题:填字母游戏

小明经常玩 LOL 游戏上瘾,一次他想挑战K大师,不料K大师说:

“我们先来玩个空格填字母的游戏,要是你不能赢我,就再别玩LOL了”。

K大师在纸上画了一行n个格子,要小明和他交替往其中填入字母。

并且:

1. 轮到某人填的时候,只能在某个空格中填入L或O
2. 谁先让字母组成了“LOL”的字样,谁获胜。
3. 如果所有格子都填满了,仍无法组成LOL,则平局。

小明试验了几次都输了,他很惭愧,希望你能用计算机帮他解开这个谜。

本题的输入格式为:
第一行,数字n(n<10),表示下面有n个初始局面。
接下来,n行,每行一个串(长度<20),表示开始的局面。
  比如:“******”, 表示有6个空格。
  “L****”,   表示左边是一个字母L,它的右边是4个空格。

要求输出n个数字,表示对每个局面,如果小明先填,当K大师总是用最强着法的时候,小明的最好结果。
1 表示能赢
-1 表示必输
0 表示可以逼平


例如,
输入:
4
***
L**L
L**L***L
L*****L

则程序应该输出:
0
-1
1
1

资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

/*LOL填字游戏
我方先填 
*/
#include<iostream>
#include<cstdlib>
#include<string> 
using namespace std;

int is_lol(string x){
    /*1表示能赢
    0表示平局 
    -1表示输 
    */
    int len=x.length(); 
    if(x.find("LOL")!=string::npos) return -1;//当我方开始填时已出现LOL时,则我方输 
    if(x.find("*")==string::npos) return 0;//当没有出现LOL时,且没有空格则为平局 
    int ping=0;//先假设为平局 
    for(int i=0;i<len;i++){
        if(x[i]=='*'){
            x[i]='L';
            switch(is_lol(x))
            {
                case -1: return 1;//当我方填完后,出现LOL,则我方赢 
                case 0: ping=1;//当我方填完后,没有空格,则为平局 
            }
            x[i]='O';
                switch(is_lol(x))
            {
                case -1: return 1;//当我方填完后,出现LOL,则我方赢 
                case 0: ping=1;//当我方填完后,没有空格,则为平局 
            }
            x[i]='*';
    }
    }
    if(ping) return 0;//如果存在平局,则结果为平局,否则即输 
    return -1;
}

int n;
int main(){
    cin>>n;
    while(n--){
    	string s;
    	cin>>s;
    	cout<<is_lol(s)<<endl;
    }
    return 0;
} 

上面的代码只能过一部分测试用例,别的测试用例会超时,下面是AC代码,来自https://blog.dotcpp.com/I7I08I9047/8791

#include <bits/stdc++.h>
constexpr auto Inf = 0X3F3F3F3F;
typedef long long LL;
using namespace std;
 
namespace IO {
    inline LL read() {
        LL o = 0, f = 1; char c = getchar();
        while (c < '0' || c > '9') { if (c == '-') f = -1; c = getchar(); }
        while (c > '/' && c < ':') { o = o * 10 + c - '0'; c = getchar(); }
        return o * f;
    }
    inline char recd() {
        char o; while ((o = getchar()) != 'Q' && o != 'C'); return o;
    }
}
using namespace IO;
 
const int SIZE = 1E7 + 7;
string ovo; int M[SIZE], MAP[233];
 
int Hash() {
    unsigned long long v = 0;
    for (int pos = 0; ovo[pos]; pos++) v = v * 3 + MAP[ovo[pos]];
    return v % 9817117;
}
 
/* 993217 492253 9817117 */
 
int F() {
    int u = Hash();
    if (M[u] != Inf) return M[u];
    if (ovo.find("LOL") != string::npos) return M[u] = -1;
    if (ovo.find("*") == string::npos) return M[u] = 0;
    int res = -1;
    for (int pos = 0; ovo[pos] && res != 1; pos++)
        if (ovo[pos] == '*') {
            ovo[pos] = 'L', res = max(res, -F());
            if (res != 1)
                ovo[pos] = 'O', res = max(res, -F());
            ovo[pos] = '*';
        }
    return M[u] = res;
}
 
int main() {
    MAP['*'] = 0, MAP['L'] = 1, MAP['O'] = 2;
    int N, BIT = sizeof M; cin >> N;
    while (N--) {
        memset(M, Inf, BIT);
        cin >> ovo, cout << F() << endl;
    }
}


5、

标题:区间移位

数轴上有n个闭区间:D1,...,Dn。

其中区间Di用一对整数[ai, bi]来描述,满足ai < bi。

已知这些区间的长度之和至少有10000。

所以,通过适当的移动这些区间,你总可以使得他们的“并”覆盖[0, 10000]

——也就是说[0, 10000]这个区间内的每一个点都落于至少一个区间内。

你希望找一个移动方法,使得位移差最大的那个区间的位移量最小。

具体来说,假设你将Di移动到[ai+ci, bi+ci]这个位置。你希望使得maxi{|ci|} 最小。

【输入格式】
输入的第一行包含一个整数n,表示区间的数量。

接下来有n行,每行2个整数ai, bi,以一个空格分开,表示区间[ai, bi]。

保证区间的长度之和至少是10000。

【输出格式】
输出一个数字,表示答案。如果答案是整数,只输出整数部分。

如果答案不是整数,输出时四舍五入保留一位小数。

【样例输入】
2
10 5010
4980 9980

【样例输出】
20

【样例说明】
第一个区间往左移动10;第二个区间往右移动20。

【样例输入】
4
0 4000
3000 5000
5001 8000
7000 10000
【样例输出】
0.5
【样例说明】
第2个区间往右移0.5;第3个区间往左移0.5即可。

【数据规模与约定】
对于30%的评测用例,1 <= n <= 10;
对于100%的评测用例,1 <= n <= 10000,0 <= ai < bi <= 10000。


资源约定:
峰值内存消耗 < 256M
CPU消耗  < 1000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

呜呜.....感觉第八届A组的题目比其他届的题目难啊,这道题也是不会做?

贴上大佬对题目的解析,二分法https://blog.youkuaiyun.com/KIKO_caoyue/article/details/87922292

6、


标题:数组操作

给出一个长度为 n 的数组 {A},由 1 到 n 标号 , 你需要维护 m 个操作。
操作分为三种,输入格式为:

1 L R d,将数组中下标 L 到 R 的位置都加上 d,即对于 L<=i<=R,执行A[i]=A[i]+d。

2 L1 R1 L2 R2,将数组中下标为 L1 到 R1 的位置,赋值成 L2 到 R2 的值,保证 R1-L1=R2-L2。
换句话说先对 0<=i<=R2-L2 执行 B[i]=A[L2+i],再对 0<=i<=R1-L1 执行 A[L1+i]=B[i],其中 {B} 为一个临时数组。

3 L R,求数组中下标 L 到 R 的位置的和,即求出 ∑_(i=L到R) A_i 。

输入格式:
从标准输入读入数据。
第一行一个整数 Case,表示测试点编号,其中 Case=0 表示该点为样例。
第二行包含两个整数 n,m。保证 1<=n,m<=10^5。
第三行包含 n 个整数 A_i,表示这个数组的初值。保证 0<=A_i<=10^5。
接下来 m 每行描述一个操作,格式如问题描述所示。
对于操作中提到每个数,满足 0<=d<=10^5,1<=L<=R<=n,1<=L1<=R1<=n,1<=L2<=R2<=n,R1-L1=R2-L2。

输出格式:
输出到标准输出。
对于每次 3 操作输出一行一个数,表示求和的结果。


样例输入:
0
5 6
1 2 3 4 5
2 1 3 3 5
3 3 5
1 2 4 2
3 3 5
2 1 3 3 5
3 1 5

样例输出:
14
18
29

----------------------------
测试点      n,m           其他约束
----------------------------
1,2      <=10^3           无
3,4      <=10^5           没有2操作
5,6,7     <=10^5       n 为偶数,且所有2操作满足 L1=1,R1=n/2  ,L2=n/2+1,R2=n
8,9,10      <=10^5       无


资源约定:
峰值内存消耗 < 2048M
CPU消耗  < 2000ms

请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。

所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。

注意: main函数需要返回0
注意: 只使用ANSI C/ANSI C++ 标准,不要调用依赖于编译环境或操作系统的特殊函数。
注意: 所有依赖的函数必须明确地在源文件中 #include <xxx>, 不能通过工程设置而省略常用头文件。

提交时,注意选择所期望的编译器类型。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值