第一次参加蓝桥杯的感想和总结

1、本次比赛整体而言其实是发挥出了正常的水平的,考试的发挥也算正常(有点受考试环境的影响:1、考试题目以图片形式给出2、控制台复制粘贴受限,但是这都不是主要的原因,),但是远远低于了我对自己的预期,没想到自己做这类题目竟然会遇到如此大的障碍,究其根本还是平时相关的练习不够,经常思维能力没有得到很好的提升,很多时候去做题只是按照固定的专题去做,导致有一些不确定范围的题目就完全没有思路,然后还有一大很严重的缺点就是,经常做题没有花很多时间去思考,不懂就直接去看题解了,甚至很多时候还会找借口说这题太难了,说什么时间不允许(有的时候确实时间并不是那么充裕),但是后续也没有安排时间去搞懂,导致我看似做了很多题(其实也不算多),但是能力(特别是思维能力)没有得到提升。

出成绩了:其实结果在我的意料之中,只有一个b组三等奖,其实这个成绩在考试之前我根本就不会相信,因为我觉得我正常发挥完全可以省一的,就是失误了,也有省二,但是不管是从考试来看,还是从真正对题目的题解来看,我现在的水平的确不足以省一,不过不要紧,我已经意识到自己做题途中的最大的问题了,这次一定要汲取教训,争取以后拿回属于自己的成绩。

一、组队

作为篮球队教练,你需要从以下名单中选出 1 号位至 5 号位各一名球员,组成球队的首发阵容。
每位球员担任 1 号位至 5 号位时的评分如下表所示。请你计算首发阵容 1 号位至 5 号位的评分之和最大可能是多少?

本题作为本次比赛的第一题,我是有点懵的,以前不都是计算日期吗!,拿到这题我想都没想直接在草稿纸上开始算了,找出每一列的最大的几个值和对应的编号:

第一列:98(17) 97(1)
第二列:99(10\20)
第三列:99(17) 98(15)
第四列:98(17) 97(11\15)
第五列:98(12\15\18)

尽量选择每列中的最大值,但是又要保证不能同一编号(17)的人被选多次,
所以一种解决方案就是:98(17) + 99(10) + 98(15) + 97(11) + 98(12) = 490

二、年号字串

小明用字母A 对应数字1,B 对应2,以此类推,用Z 对应26。对于27以上的数字,小明用两位或更长位的字符串来对应,例如AA 对应27,AB 对应28,AZ 对应52,LQ 对应329。
请问2019 对应的字符串是什么?

这道题我不知道我是zz还是当时想啥了
我的解题思路:
A-1 B-2 C-3 … Z-26
AA-27 AB-28 … AZ-52
我一想,2019/26=77 2019%26=17,是不是就是在第78行的第17个数? 然后每一行的开头就是A开头,第一行前面0个A,第二行1个A,那78行前面不就是77个A吗,然后对应到17个字母就是Q,那答案不就是AAA(77个)Q吗,我还想,这题目是不是脑残啊, 而且我打印出来还不好去复制(其实可以输出到文件的),那我只能一个个的输了???然后我真的就自己去输了,真是严重影响我的心态了…。
后来,考完之后看知乎上的题解,为什么是BYQ!,然后我就又分析了一下,题目的最后还有一个329(329/26=12 329%26=17)啊,要是按照我想法,那岂不是12个A加上一个Q吗,但是并不是,所以只能怪考试的时候审题不仔细阅读理解杯吗,给出正确分析思路:
A=1x260 B=2x260 … Z=26x260
AA=1x261+1x260 AB=1x261+2x260 … AZ=1x261+26x260
BA=2x261+1x260
这不就是26进制嘛!!!
LQ =12x261+17x260=329
所以2019(十进制)该怎么转换成26进制呢
除留取余法不就好了
2019/26=77 2019%26=17(Q)
77/26=2 77%26 = 25(Y)
2/26 = 0 2%26 = 2(B)
所以结果就是BYQ

三、数列求和

给定数列1, 1, 1, 3, 5, 9, 17, …,从第4 项开始,每项都是前3 项的和。求
第20190324 项的最后4 位数字。

刚开始拿到这题,心里一想,哎,终于有道肯定能够确定的题目了,直接开一个20190324大小的数组呗,从第四项开始算起,诶,等等,会不会超int了,那我开long long吧,然后我就出来出现了下面的代码

#include <iostream>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAX = 20190324+5;
ll a[MAX];
int main()
{a[1] = 1; a[2] = 1; a[3] = 1;for(int i = 4; i <= 20190324; i++){a[i] = (a[i-1] + a[i-2] + a[i-3]);}cout << a[20190324] << endl;//因为输出的后面四位的0115,我就填上了0115
}

然后我还觉得这应该不会错吧,反正最后的结果都是在long long的范围之内(19位数)(只是因为我看见最后的结果没有出现负值,但其实多打印几个数就知道了,根本早就已经爆ll了好吧)
基本数据类型的范围
但是在赛后一测试,别说20190324了,就连100以内的数都超long long,我这数学意识差的1p,然后就…知道了,因为是取后面的四位数,所以做如下处理就好了(甚至数组都不需要开,直接用四个变量就可以了)

 for(int i = 4; i <= 20190324; i++){a[i] = (a[i-1] + a[i-2] + a[i-3]) % 10000;}cout << a[20190324] << endl;

答案:4659

四、数的分解

把2019 分解成3 个各不相同的正整数之和,并且要求每个正整数都不包含数字 2 和 4,一共有多少种不同的分解方法?
注意交换3个整数的顺序被视为同一种方法,例如1000+1001+18 和 1001+1000+18 被视为同一种。

这道题目我考试的时候是贴的如下代码:

#include <iostream>
#include <algorithm>
using namespace std;
int main()
{int cnt = 0;for(int i = 1; i <= 2019; i++){for(int j = 1; j <= 2019; j++){for(int k = 1; k <= 2019; k++){if(Judge(i) && Judge(j) && Judge(k) && (i + j + k) == 2019 && i < j && j < k){cnt++;}}}}cout << cnt << endl;
}

考试的时候好像跑的还挺快的,结果我也不记得了,但是换作自己的电脑就根本跑的很慢,我感觉我的思维很迟钝啊这道题目难道不会想一下,换成下面的代码吗?!!

 int cnt = 0;for(int i = 1; i <= 2019; i++){for(int j = i+1; j <= 2019; j++){int k = 2019 - (i+j);//别开三个for循环,不然电脑跑的恰亏if(k > j){if(Judge(i) && Judge(j) && Judge(k)){cnt++;}}else{break;}}}cout << cnt << endl;

五、迷宫

给出一个迷宫的平面图(下图为样例),其中1为障碍,0为可以通行的地方。

010000
000100
001001
110000

迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这 个它的上、下、左、右四个方向之一。 对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫, 一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。

对于下面这个更复杂的迷宫(30 行 50 列),请找出一种通过迷宫的方式, 其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。 请注意在字典序中D<L<R<U。

01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000

划重点了可以说我本次比赛就是被这道题目耗死了虽然其他题目也做的很差,刚开始拿到这道题,我一想,这道题目不是前一段时间做过的吗, 只是这道题的数据规模有点大啊,然后我就想用dfs吧因为dfs相对来说写的更快,而且思路更加清晰,然后就写了一会,但是根本跑不出来结果,出现运行错误,我就有点懵了,是不是因为数据规模大导致爆栈了呢,然后我就先不纠结了,等会用bfs来写,…(写后面的题目中),大概还有一个半小时的时间吧,我又来写这道题目了,直接开始bfs,然后写着写着发现bfs我不会记录路径啊(我怕不是有点傻啊,前段时间才学会bfs记录路径的,现在又不记得了),我就又傻着去改写dfs了(怕可能是哪里没注意到),然后跑样例都跑不出(还是RE了),我就很奇怪了,开始一步步的调 …,结果发现了输入出了问题,见下面代码:

 for(int i = 1; i <= 30; i++){for(int j = 1; j <= 50; j++){scanf("%c",&g[i][j]);}}

调试了半天,发现是因为读取的是字符(为什么不读取int呢?因为读int它咋知道你读的是0,还是01,还是010啊),读取字符的坑就出来了,读取下一行的时候会首先读取前一行的末尾换行符,然后就读乱了,然后在第一层for循环下加一个:

getchar();

即可。

好,输入问题已经解决了,但是跑样例还是跑不出来,我就不知道该咋做了,乱填一个答案也填不好,然后就不会了…
考完之后,看见很多人说就是bfs,那我的问题就是bfs不会记录路径,我就开始重新学习如何记录路径,然后我就写下了如下的代码:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <queue>
using namespace std;char g[30+5][50+5];
int dir[4][2] = {{1,0},{0,-1},{0,1},{-1,0}};
char t[4] = {'D','L','R','U'};struct Node
{int x,y;//记录下节点的位置char Dir;//到达下一个节点的走向
};Node pre[30+5][50+5];//记录下最短路径上每个节点的前置节点 void dfs(int x,int y)//dfs打印出具体走的路径
{if(x == 1 && y == 1){return;}else{int pre_x = pre[x][y].x;int pre_y = pre[x][y].y;dfs(pre_x,pre_y);cout << pre[x][y].Dir;//printf("(%d,%d) ",pre_x,pre_y);}
}void bfs()//bfs求最短路
{queue <Node> q;Node start;start.x = 1; start.y = 1;q.push(start);Node next,tmp;while(!q.empty()){tmp = q.front();q.pop();if(tmp.x == 30 && tmp.y == 50){/* 走到了终点的位置,要根据终点找到前置节点,一直往前面找 直到找到起始节点(1,1),然后打印出来走的方向,使用dfs就可以了。 */dfs(30,50); return;}for(int i = 0; i < 4; i++){next.x = tmp.x + dir[i][0];next.y = tmp.y + dir[i][1];if(next.x >= 1 && next.x <= 30 && next.y >= 1 && next.y <= 50&& g[next.x][next.y] == '0' ){g[next.x][next.y] = '1';q.push(next);tmp.Dir = t[i];/* 要记录下该节点的前置节点 */pre[next.x][next.y] = tmp;}}}
}int main()
{for(int i = 1; i <= 30; i++){for(int j = 1; j <= 50; j++){scanf("%c",&g[i][j]);}getchar();//记得去除行末换行符 }bfs();return 0;
}

答案:DDDDRRURRRRRRDRRRRDDDLDDRDDDDDDDDDDDDRDDRRRURRUURRDDDDRDRRRRRRDRRURRDDDRRRRUURUUUUUUULULLUUUURRRRUULLLUUUULLUUULUURRURRURURRRDDRRRRRDDRRDDLLLDDRRDDRDDLDDDLLDDLLLDLDDDLDDRRRRRRRRRDDDDDDRR

六、特别数的和

小明对数位中含有 2、0、1、9 的数字很感兴趣(不包括前导0),在1 到 40 中这样的数包括1、2、9、10 至 32、39 和 40,共 28 个,他们的和是 574。请问,在 1 到n 中,所有这样的数的和是多少?

【输入格式】
输入一行包含一个整数n。

【输出格式】
输出一行,包含一个整数,表示满足条件的数的和。

【样例输入】
40

【样例输出】
574

【评测用例规模与约定】
对于20% 的评测用例,1≤n≤10 1 \leq n \leq 101≤n≤10。
对于50% 的评测用例,1≤n≤100 1 \leq n \leq 1001≤n≤100。
对于80% 的评测用例,1≤n≤1000 1 \leq n \leq 10001≤n≤1000。
对于所有评测用例,1≤n≤10000 1 \leq n \leq 100001≤n≤10000。

这题就很简单了为啥这么简单的一道题放在t6的位置,但是,刚开始我还很疑惑,数据规模达到了1e4,虽说O(n)的for循环并不会超时(某本书上看到的,当时间限制为1s,运算量达到了1e6以上就可能会超时了),我一想,虽然没有超过1e6,但是对于每个数都要做一次判断,那会不会出现有的数超时呢? 其实根本不会出现这种超时的情况,假设n为1e4,每个数都是五位数,那也才是5x1e4 << 1e6 ,所以就放心大胆的开for循环吧,(我考试的时候,想着打表,然后发现打了表也不能复制出来结果,其实非得打表复制出结果也可以,直接打印到文件中再复制就好了)。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;bool Judge(int x)
{while(x){int t = x % 10;if(t == 2 || t == 0 || t == 1 || t == 9){return true;;}x = x / 10;}return false;
}int main()
{int n;cin >> n;int sum = 0;//这里甚至不需要开long long,因为根本不会爆intfor(int i = 1; i <= n; i++){if(Judge(i)) sum += i;}cout << sum << endl;return 0;
}

七、完全二叉树的权值

给定一棵包含N 个节点的完全二叉树,树上每个节点都有一个权值,按从上到下、从左到右的顺序依次是A1,A2,…,AN,如下图所示:

现在小明要把相同深度的节点的权值加在一起,他想知道哪个深度的节点权值之和最大?如果有多个深度的权值和同为最大,请你输出其中最小的深度。
注:根的深度是1。

【输入格式】
第一行包含一个整数N
第二行包含N 个整数A1,A2,…,AN

【输出格式】
输出一个整数代表答案

【样例输入】
7
1 6 5 4 3 2 1

【样例输出】
2
【评测用例规模与约定】
对于所有评测用例,1≤N≤100000 ,−100000≤Ai≤100000

这道题目我可能是被前面的题目给影响心态了还有一点关键的就是对完全二叉树的性质全忘干净了
首先来复习下二叉树的性质
还补一个重要性质:

n个节点的完全二叉树深度为:(int)log2(n)+1
完全二叉树就是除了最后一层不是满的,其他层全都是满的,每一层的节点的个数为2i-1,就只是除了最后一层不是,但是也只要遍历到最后就可以了:
第1层:1
第2层:2
第3层:4
最后一(i)层:<=2i-1

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;typedef long long ll;
const ll  INF = 0x3f3f3f3f3f3f3f3f;
int n;
ll w[MAX];ll pow_int(int x,int y)//为啥我自己写了个pow函数呢?因为math库里面的pow()函数返回的是double,为了避免出现精度问题。
{ll sum = 1;for(int i = 1; i <= y; i++){sum *= x;  }return sum;
}int main()
{cin >> n;for(int i = 1; i <= n; i++){cin >> w[i];}ll max_w = -INF;//权值之和最大int min_d = 1;//最小的深度int i = 1;for(int k = 1; ; k++)//从深度为1,第一个值开始枚举(这里还可以算出最大深度,以最大深度为末尾边界){ll sum = 0;//记录该层的最大值 int num = pow_int(2,k-1);//记录下该层的节点个数 int t = i;//标记下起始i的值 while(i <= num+t-1 && i <= n){sum += w[i++];}if(sum > max_w){max_w = sum;min_d = k;}if(i > n){break;}}cout << min_d << endl;return 0;
}

八、等差数列

数学老师给小明出了一道等差数列求和的题目。但是粗心的小明忘记了一部分的数列,只记得其中N 个整数。
现在给出这N 个整数,小明想知道包含这N 个整数的最短的等差数列有几项?
【输入格式】
输入的第一行包含一个整数N。
第二行包含N 个整数A1,A2,…,AN(注意: A1, A2, 并不一定是按等差数列中的顺序给出)

【输出格式】
输出一个整数表示答案。

【样例输入】
5
2 6 4 10 20

【样例输出】
10

【样例说明】
包含2、6、4、10、20 的最短的等差数列是2、4、6、8、10、12、14、16、18、20

【评测用例规模与约定】
对于所有评测用例,2≤N≤100000 ,0≤Ai≤109

首先给出我的起始思路:

因为n个整数不是按照顺序给出的,所以我先给它排个序,因为要使得等差数列的长度尽可能小嘛,所以公差应该是尽可能大的(只有公差尽可能大才能使得覆盖范围大,从而使得长度尽可能小),但是最大的公差是最少呢?因为第一个数和第二个数都要在等差数列之中,所以最大的公差就是a[2]-a[1]了,然后我就开始枚举其中的值,能够使得包含n个整数的每个值就ok。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAX = 1e5+5;
int n;
int a[MAX];int main()
{cin >> n;for(int i = 1; i <= n; i++){cin >> a[i];}sort(a+1,a+1+n);int max_d = a[2] - a[1];if(max_d == 0){//如果两个整数相等,其实也就意味n个数都是相等的,那么最短的等差数列长度就是ncout << n << endl;return 0; }int min_len;for(int d = max_d; d >= 1; d--)//从最大的公差开始枚举,看能不能覆盖到每一个值{bool flag = true;for(int i = 2; i <= n; i++){if((a[i]-a[1]) % d != 0){//a[i]-a[1]不能够整除d,说明a[i]不能包括在以a[1]为起点,公差为d的等差数列中,要break出去,枚举更小的dflag = false;break; }}if(flag){//如果能够覆盖到每一个值,而且公差又是尽可能大的,那等差数列长度就是最小的min_len = (a[n] - a[1])/d + 1;cout << min_len << endl;break;}} return 0;
}

其实我也不知道对了没有(应该对了),我参考了下网上其他人的思路:

直接给数组从小到大排个序,因为要使得每一项都被包含,意味着(前一项-后一项)一定是公差的可能情况,然后求出所有差值的最大公约数,就是能够覆盖掉每个值,而且此时公差不能再大了(如果再大就会导致有些数覆盖不到),
例如:两个数的差值情况为2 2 4 10 最大公约数为2
如果公差为4或者10,就不能保证差值为2的那两个数被覆盖了
再比如:4 8 10 16 最大公约数为2
如果公差为4,那8(两个4)是可以的,但是10(4+4+2)就不可以了

标程:

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAX = 1e5+5;
int n;
int a[MAX];int gcd(int a,int b)
{return b?gcd(a,a%b):a;
}int main()
{cin >> n;for(int i = 1; i <= n; i++){cin >> a[i];}sort(a+1,a+1+n);int d = a[2] - a[1];if(d == 0){//如果两个整数相等,其实也就意味n个数都是相等的,那么最短的等差数列长度就是ncout << n << endl;return 0; }int d = a[2] - a[1];if(d == 0){cout << n << endl;return 0; }for(int i = 2; i <= n; i++){int t = a[i] - a[i-1];d = gcd(d,t);}cout << (a[n]-a[1])/d + 1 << endl;return 0;
}

九、后缀表达式

给定N 个加号、M 个减号以及N + M + 1 个整数A1,A2,…,A(M+N+1),小明想知道在所有由这 N 个加号、M 个减号以及 N + M +1 个整数凑出的合法的后缀表达式中,结果最大的是哪一个?
请你输出这个最大的结果。
例如使用1 2 3 + -,则“2 3 + 1 -” 这个后缀表达式结果是4,是最大的。

【输入格式】
第一行包含两个整数N 和M。
第二行包含N + M + 1 个整数A1,A2,…,A(M+N+1)

【输出格式】
输出一个整数,代表答案。

【样例输入】
1 1
1 2 3
【样例输出】
4

【评测用例规模与约定】
对于所有评测用例,1≤N,M≤100000,−109≤Ai≤ 109

对于这道题目我其实根本就没有花什么时间去思考,我看见这是一道25分的题目,而且还涉及到后缀表达式(后缀表达式怎么了!不也就是之前学过的吗,慌什么慌呢!),但是在赛后他们说其实很简单:

n个+、m个-、总共n+m+1个数(就是在这么多个数中插入n+m个符号而已),然后要求后缀表达式最大,后缀表达式唯一对应中缀表达式啊,那后缀最大岂不是就是中缀最大了,所以其实就是看怎么放置位置可以使得(中缀)表达式的值最大,所以这么看来的思路就是:
直接从大到小排个序,然后前n+1个数两两相加,最后减去n+2开始的后面m个数的和就可以了。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
using namespace std;typedef long long ll;
const int MAX = 1e5+5;
int n,m;
ll a[MAX];int cmp(int a,int b)
{return a > b;
}int main()
{ll sum1 = 0;for(int i = 1; i <= n + 1; i++){sum1 += a[i];}ll sum2 = 0;for(int i = n + 2; i <= n + m + 1; i++){sum2 += a[i];}ll sum = sum1 - sum2;cout << sum << endl;
}

参考了网上一位大佬的题解,感觉还是有一点不太明白:

首先做一个预处理:按绝对值从大到小排个序
因为只有’+‘和’-’,所以可以看作是n+m+1个数相加,减去一个数看作加上这个数的相反数,考虑负数的个数和’-‘号个数m的关系:
1.负数个数 == m => 可以直接将所有的负数前面放置’-’,然后就是所有数的绝对值相加即可。
2.负数个数 > m => 可以将绝对值大的m个负数变为正数,然后就是前面的正数(包括原本的和重新置为的正数) + 剩余的负数即可。
3.负数个数 < m => 可以将所有的负数都变成正数,然后还有剩余的几个负号,放到绝对值小的几个数上,然后求个和即可。
不是很理解的点:
为啥一个数前面可以放几个符号(比如第三种情况,首先在所有的负数前面放置了-号,使得全部变为正数,然后可能某些负数的绝对值比较小,排个序在后面,又要在前面放负号变成负数)

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <climits>
#include <cstring>
#include <string>
#include <algorithm>
#include <vector>
#include <deque>
#include <list>
#include <utility>
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <bitset>
#include <iterator>using namespace std;typedef long long ll;
const int inf = 0x3f3f3f3f;
const ll  INF = 0x3f3f3f3f3f3f3f3f;
const int PI = acos(-1);
const int E = exp(1);
const int MOD = 1e9+7;
const int MAX = 1e5+5;
int n,m;
ll a[MAX];int cmp(int a,int b)
{return abs(a) > abs(b);
}int main()
{int fu_num = 0;int zheng_num = 0; cin >> n >> m;for(int i = 1; i <= n + m + 1; i++){cin >> a[i]; if(a[i] < 0) fu_num++;}zheng_num = n+m+1 - fu_num;sort(a+1,a+1+(n+m+1),cmp);ll sum = 0;if(fu_num == m){for(int i = 1; i <= n + m + 1; i++){sum += abs(a[i]);}}else if(fu_num > m){int cnt = 0;for(int i = 1; i <= n + m + 1; i++){if(a[i] < 0 && cnt != m){sum += abs(a[i]); cnt++;}else{sum += a[i];}}}else if(fu_num < m){int t_m = m - fu_num;for(int i = 1; i <= n + m + 1; i++){if(i > n+m+1 - t_m){sum -= abs(a[i]);}else{sum += abs(a[i]); }}}cout << sum << endl;return 0;
}

第十题:灵能传输

【题目背景】 在游戏《星际争霸 II》中,高阶圣堂武士作为星灵的重要 AOE 单位,在 游戏的中后期发挥着重要的作用,其技能”灵能风暴“可以消耗大量的灵能对 一片区域内的敌军造成毁灭性的伤害。经常用于对抗人类的生化部队和虫族的 刺蛇飞龙等低血量单位。

【问题描述】 你控制着 n 名高阶圣堂武士,方便起见标为 1,2,··· ,n。每名高阶圣堂武士 需要一定的灵能来战斗,每个人有一个灵能值 ai 表示其拥有的灵能的多少(ai 非负表示这名高阶圣堂武士比在最佳状态下多余了 ai 点灵能,ai 为负则表示这 名高阶圣堂武士还需要 −ai 点灵能才能到达最佳战斗状态)。现在系统赋予了 你的高阶圣堂武士一个能力,传递灵能,每次你可以选择一个 i ∈ [2,n−1],若 ai ≥ 0 则其两旁的高阶圣堂武士,也就是 i−1、i + 1 这两名高阶圣堂武士会从 i 这名高阶圣堂武士这里各抽取 ai 点灵能;若 ai < 0 则其两旁的高阶圣堂武士, 也就是 i−1,i+1 这两名高阶圣堂武士会给 i 这名高阶圣堂武士 −ai 点灵能。形 式化来讲就是 ai−1+ = ai,ai+1+ = ai,ai−= 2ai。 灵能是非常高效的作战工具,同时也非常危险且不稳定,一位高阶圣堂 武士拥有的灵能过多或者过少都不好,定义一组高阶圣堂武士的不稳定度为 maxni=1|ai|,请你通过不限次数的传递灵能操作使得你控制的这一组高阶圣堂武士的不稳定度最小。

【输入格式】
本题包含多组询问。输入的第一行包含一个正整数 T 表示询问组数。 接下来依次输入每一组询问。 每组询问的第一行包含一个正整数 n,表示高阶圣堂武士的数量。 接下来一行包含 n 个数 a1,a2,··· ,an。

【输出格式】
输出 T 行。每行一个整数依次表示每组询问的答案。

【样例输入】 3 3 5 -2 3 4 0 0 0 0 3 1 2 3
【样例输出】 3 0 3
【样例说明】
对于第一组询问: 对 2 号高阶圣堂武士进行传输操作后 a1 = 3,a2 = 2,a3 = 1。答案为 3。 对于第二组询问:
这一组高阶圣堂武士拥有的灵能都正好可以让他们达到最佳战斗状态。

【样例输入】 3 4 -1 -2 -3 7 4 2 3 4 -8 5 -1 -1 6 -1 -1
试题J: 灵能传输 16
第十届蓝桥杯大赛软件类省赛 C/C++ 大学 B 组
【样例输出】 5 7 4

【样例输入】 见文件trans3.in。
【样例输出】 见文件trans3.ans。

【数据规模与约定】 对于所有评测用例,T ≤3,3≤n≤300000,|ai|≤109。 评测时将使用 25 个评测用例测试你的程序,每个评测用例的限制如下:

注意:本题输入量较大请使用快速的读入方式。

这道题目,我考试的时候就基本上没去看了,目前也时间不是很充足可能这题一时半会驾驭不了,先码在这:
题目讲解(c\c++ ab组 java ab组视频讲解)

好了,这也算是自己的第一篇发布出来的总结和题解,我以后会坚持写题解的,也希望自己的能力可以逐步提升上来,以后还有很多比赛可以参加,为了不让自己遗憾,现在就努力吧,争取明年能够顺序进入国赛,并拿到国二或以上的成绩!!!

第十届蓝桥杯省赛C/C++B组题解与感想相关推荐

  1. 2019第十届蓝桥杯省赛C/C++B组题解

    作为很久很久没有写过算法题的考研狗 OvO(是这样的,卑微考研),我于今年再次参加了蓝桥杯... 大家都说这次蓝桥杯简单,我也是这么觉得的(或者说是我运气好),或者说是考细节吧(虽然我也没怎么考虑细节 ...

  2. 【2019第十届蓝桥杯省赛C/C++B组题解】(非官方题解)

    A. 数数题. 答案:490 B. 26进制模拟. 答案:BYQ C. 类似fib数列求值,递推一下就好. 答案:4659 D. 注意两个坑点,一个是正整数,所以枚举要从1开始.第二个坑点是互不相同的 ...

  3. 2019 第十届蓝桥杯省赛 Java 大学 C 组 题解

    试题 A: 求和 本题总分:5 分 [问题描述] 小明对数位中含有 2.0.1.9 的数字很感兴趣,在 1 到 40 中这样的数包 括 1.2.9.10 至 32.39 和 40,共 28 个,他们的 ...

  4. 2019年第十届蓝桥杯 - 省赛 - C/C++研究生组 - G. 扫地机器人

    2019年第十届蓝桥杯 - 省赛 - C/C++研究生组 - G. 扫地机器人 Ideas 首先我们根据数学常识可以知道,当每个机器人清扫的范围差不多时,最好都是 N / K,花的时间应该是最少的. ...

  5. java迷宫类编程题_第十届蓝桥杯省赛java类B组 试题 E:迷宫 (动态规划之回溯法)...

    问题描述 试题 E: 迷宫 [问题描述] 下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可 以通行的地方. 010000 000100 001001 110000 迷宫的入口为 ...

  6. 2018第九届蓝桥杯省赛c/c++ A 组题解(填空部分)

    第九届蓝桥杯省赛c/c++ A 组题解(部分) 1 分数 等比数列求前n项和 2 星期一 解题思路: 3 乘积尾零 4 第几个幸运数 5 打印图形 第九届蓝桥杯省赛c/c++ A 组题解(部分) 1 ...

  7. 2021年第十二届蓝桥杯省赛C/C++B组题解总结

    前几天(2021.4.18)刚刚比完了2021年第十二届蓝桥杯省赛,本人参加的是软件组C++B组的比赛,本文包括了这一届C++B组的题目以及部分题解.感悟和总结. 目录 试题A.空间 试题B.卡片 试 ...

  8. 第十届蓝桥杯国赛java_2019年第十届蓝桥杯国赛总结(JavaA组)

    JavaA组国二,可以报销了~ JA死亡之组可不是盖的,rank12的排名还是拿不到国一啊(只有五个.. 出成绩的一刻波澜不惊,毕竟去年有国一了不慌哈哈哈 不过对我来说这个结果还算意料之外吧,毕竟大三 ...

  9. 第十届蓝桥杯省赛C/C++B组省赛题解(留下了不学无术的泪水)

    本人广东某本科院校大二O-O,第二次参加蓝桥杯,大一第一次参加 划水拿了个三等- (更新 拿了省一 好开心 要去北京啦 今天还是我生日!) 废话不多说进入正题!! 第一题 试题 A: 组队 本题总分: ...

最新文章

  1. ubuntu安装pip3
  2. DPDK vhost-user研究(九)
  3. 【IOC 控制反转】Android 视图依赖注入 ( 视图依赖注入步骤 | 视图依赖注入代码示例 )
  4. linux 记一次链路聚合
  5. PHP初级学习之PHP文件
  6. magento2 所需要php 扩展,Magento2如何通过Composer安装插件扩展
  7. IDEA使用过程中相应的配置和设置(如编码设置、窗口调整以及config.xml文件模板创建、工程打开方式、约束文件)
  8. Oracle linux R5-U7中YUM 源配置
  9. android studio(1)---探索Android Studio
  10. 【SSH网上商城项目实战11】查询和删除商品功能的实现
  11. Excel不好吗?为什么非要用Python做数据分析
  12. 柳氏管理学:自己不会,就要勤做笔记
  13. 【线段树入门题目集】
  14. 抖音直播违规行为与敏感词处罚,直播必备干货大全丨国仁网络
  15. TCP与UDP的区别
  16. jsonp的原理与实现
  17. java8中lambda的用法(map转list,list转map等等)
  18. 视频到图片(每隔几帧保存一张图片)opencv实现
  19. 专业导师告诉你,有哪些51单片机教程值得大力推荐
  20. 计算机二级的简单项目,2016年计算机二级考试VB简单综合应用题冲刺

热门文章

  1. 支付宝做社交缺什么?
  2. java excel条件格式设置颜色吗_EXCEL条件格式,原来数据也可以如此“色”
  3. iOS开发常用第三方库
  4. 小米note2 android,小米Note2和Note有什么区别?小米Note2对比Note详解 (全文)
  5. 百度超级链沙龙回顾 | IBM郭剑南:如何在区块链中使用数据库
  6. 微信小程序上传视频到服务器太慢,微信小程序视频播放加载很慢
  7. MySQL之数据分组与数据透视表
  8. 互联网金融十大生意模式
  9. ubuntu20.04 关闭图形界面
  10. “游戏开发入门指南——Unity+”的食用指南