【合集内容】
ALGO-22 至 ALGO-45
【空缺】
ALGO-16 进制转换
ALGO-24 统计单词个数
蓝桥杯 ALGO-22 数的划分
蓝桥杯 ALGO-23 一元三次方程求解
问题描述:
有形如:ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在-100至100之间),且根与根之差的绝对值>=1。要求三个实根。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 double a, b, c, d; 5 6 double calc(double o) { 7 return a * o * o * o + b * o * o + c * o + d; 8 } 9 10 int main() { 11 cin >> a >> b >> c >> d; 12 for (double x = -100.0; x <= 100.0; x += 0.01) { 13 double x1 = x - 0.005, x2 = x + 0.005; 14 if (calc(x1) * calc(x2) < 0) 15 cout << fixed << setprecision(2) << x << ' '; 16 } 17 return 0; 18 }
蓝桥杯 ALGO-24 统计单词个数
蓝桥杯 ALGO-25 Car 的旅行路线
[题目][NOIP2001][蓝桥杯ALGO-25] Car 的旅行路线
蓝桥杯 ALGO-26 麦森数
问题描述:
形如2P-1的素数称为麦森数,这时P一定也是个素数。但反过来不一定,即如果P是个素数,2P-1不一定也是素数。到1998年底,人们已找到了37个麦森数。最大的一个是P=3021377,它有909526位。麦森数有许多重要应用,它与完全数密切相关。
任务:从文件中输入P(1000<P<3100000),计算2P-1的位数和最后500位数字(用十进制高精度数表示)
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 1005 5 6 int two[2] = {1, 2}; 7 int p, a[MAXN] = {1, 1}, b[MAXN], c[MAXN], bs; 8 9 void mul(int a[], int b[]) { 10 memset(c, 0, sizeof(c)); 11 for (int i = 1; i <= min(500, a[0]); i++) 12 for (int j = 1; j <= min(500, b[0]); j++) { 13 c[i + j - 1] += a[i] * b[j]; 14 if (c[i + j - 1] >= 10) 15 c[i + j] += c[i + j - 1] / 10, c[i + j - 1] %= 10; 16 } 17 a[0] = min(a[0] + b[0], 500); 18 for (int i = 1; i <= a[0]; i++) a[i] = c[i]; 19 } 20 21 int main() { 22 cin >> p; 23 cout << floor(log(2) / log(10) * p + 1); 24 while (p) { 25 bs = 1; 26 b[0] = 1, b[1] = 2; 27 while (p >= bs) { 28 p -= bs, mul(a, b); 29 bs <<= 1, mul(b, b); 30 } 31 } 32 a[1]--; 33 for (int i = 500; i >= 1; i--) { 34 if (i % 50 == 0) cout << endl; 35 cout << a[i]; 36 } 37 return 0; 38 }
蓝桥杯 ALGO-27 FBI 树
问题描述:
我们可以把由“0”和“1”组成的字符串分为三类:全“0”串称为B串,全“1”串称为I串,既含“0”又含“1”的串则称为F串。
FBI树是一种二叉树,它的结点类型也包括F结点,B结点和I结点三种。由一个长度为2N的“01”串S可以构造出一棵FBI树T,递归的构造方法如下:
1)T的根结点为R,其类型与串S的类型相同;
2)若串S的长度大于1,将串S从中间分开,分为等长的左右子串S1和S2;由左子串S1构造R的左子树T1,由右子串S2构造R的右子树T2。
现在给定一个长度为2N的“01”串,请用上述构造方法构造出一棵FBI树,并输出它的后序遍历序列。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 3005 5 6 int n, tot; 7 char a[MAXN], s[MAXN]; 8 9 char work(int x, int o) { 10 if (o == 1) return a[++tot] = s[x] == '0' ? 'B' : 'I'; 11 int l = work(x, o >> 1), r = work(x + (o >> 1), o >> 1); 12 return a[++tot] = l == r ? l : 'F'; 13 } 14 15 int main() { 16 cin >> n >> s + 1; 17 work(1, strlen(s + 1)); 18 for (int i = 1; i <= tot; i++) 19 cout << a[i]; 20 return 0; 21 }
蓝桥杯 ALGO-28 星际交流
问题描述:
人类终于登上了火星的土地并且见到了神秘的火星人。人类和火星人都无法理解对方的语言,但是我们的科学家发明了一种用数字交流的方法。这种交流方法是这样 的,首先,火星人把一个非常大的数字告诉人类科学家,科学家破解这个数字的含义后,再把一个很小的数字加到这个大数上面,把结果告诉火星人,作为人类的回 答。
火星人用一种非常简单的方式来表示数字——掰手指。火星人只有一只手,但这只手上有成千上万的手指,这些手指排成一列,分别编号为1,2,3……。火星人的任意两根手指都能随意交换位置,他们就是通过这方法计数的。
一个火星人用一个人类的手演示了如何用手指计数。如果把五根手指——拇指、食指、中指、无名指和小指分别编号为1,2,3,4和5,当它们按正常顺序排列 时,形成了5位数12345,当你交换无名指和小指的位置时,会形成5位数12354,当你把五个手指的顺序完全颠倒时,会形成54321,在所有能够形 成的120个5位数中,12345最小,它表示1;12354第二小,它表示2;54321最大,它表示120。下表展示了只有3根手指时能够形成的6个 3位数和它们代表的数字:
三进制数 123 132 213 231 312 321
代表的数字 1 2 3 4 5 6
现在你有幸成为了第一个和火星人交流的地球人。一个火星人会让你看他的手指,科学家会告诉你要加上去的很小的数。你的任务是,把火星人用手指表示的数与科 学家告诉你的数相加,并根据相加的结果改变火星人手指的排列顺序。输入数据保证这个结果不会超出火星人手指能表示的范围。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 10005 5 #define INF 1 << 30 6 7 int n, m, a[MAXN]; 8 9 int main() { 10 cin >> n >> m; 11 for (int i = 1; i <= n; i++) 12 cin >> a[i]; 13 for (int k = 1; k <= m; k++) 14 for (int i = n - 1; i >= 1; i--) 15 if (a[i] < a[i + 1]) { 16 int mi = INF, x; 17 for (int j = i + 1; j <= n; j++) 18 if (mi > a[j] && a[j] > a[i]) 19 mi = a[j], x = j; 20 swap(a[i], a[x]); 21 sort(a + i + 1, a + n + 1); 22 break; 23 } 24 for (int i = 1; i <= n; i++) 25 cout << a[i] << ' '; 26 return 0; 27 }
蓝桥杯 ALGO-29 校门外的树
问题描述:
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数 轴上的每个整数点,即0,1,2,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已 知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树 都移走后,马路上还有多少棵树。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 10005 5 6 int n, m, ans, t[MAXN], l, r; 7 8 int main() { 9 cin >> n >> m; 10 for (int i = 1; i <= m; i++) { 11 cin >> l >> r; 12 for (int j = l; j <= r; j++) 13 t[j] = 1; 14 } 15 for (int i = 0; i <= n; i++) 16 ans += !t[i]; 17 cout << ans; 18 return 0; 19 }
蓝桥杯 ALGO-30 入学考试
问题描述:
辰辰是个天资聪颖的孩子,他的梦想是成为世界上最伟大的医师。为此,他想拜附近最有威望的医师为师。医师为了判断他的资质,给他出了一个难题。医师把他带到一个到处都是草药的山洞里对他说:“孩子,这个山洞里有一些不同的草药,采每一株都需要一些时间,每一株也有它自身的价值。我会给你一段时间,在这段时间里,你可以采到一些草药。如果你是一个聪明的孩子,你应该可以让采到的草药的总价值最大。”
如果你是辰辰,你能完成这个任务吗?
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 1005 5 6 int n, m, ans, t[MAXN], v[MAXN], f[MAXN]; 7 8 int main() { 9 cin >> n >> m; 10 for (int i = 1; i <= m; i++) 11 cin >> t[i] >> v[i]; 12 for (int i = 1; i <= m; i++) 13 for (int j = n; j >= t[i]; j--) 14 f[j] = max(f[j], f[j - t[i]] + v[i]); 15 for (int i = 1; i <= n; i++) 16 ans = max(ans, f[i]); 17 cout << ans; 18 return 0; 19 }
(就是最基本的背包 DP 模板题采药问题,入学考试这个标题没太看懂)
蓝桥杯 ALGO-31 开心的金明
问题描述:
金明今天很开心,家里购置的新房就要领钥匙了,新房里有一间他自己专用的很宽敞的房间。更让他高兴的是,妈妈昨天对他说:“你的房间需要购买哪些物品,怎 么布置,你说了算,只要不超过N元钱就行”。今天一早金明就开始做预算,但是他想买的东西太多了,肯定会超过妈妈限定的N元。于是,他把每件物品规定了一 个重要度,分为5等:用整数1~5表示,第5等最重要。他还从因特网上查到了每件物品的价格(都是整数元)。他希望在不超过N元(可以等于N元)的前提 下,使每件物品的价格与重要度的乘积的总和最大。
设第j件物品的价格为v[j],重要度为w[j],共选中了k件物品,编号依次为 j1,j2,……,jk,则所求的总和为:
v[j1]*w[j1]+v[j2]*w[j2]+ …+v[jk]*w[jk]。(其中*为乘号)
请你帮助金明设计一个满足要求的购物单。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 30005 5 6 int n, m, ans, t[MAXN], v[MAXN], f[MAXN]; 7 8 int main() { 9 cin >> n >> m; 10 for (int i = 1; i <= m; i++) 11 cin >> t[i] >> v[i]; 12 for (int i = 1; i <= m; i++) 13 for (int j = n; j >= t[i]; j--) 14 f[j] = max(f[j], f[j - t[i]] + v[i] * t[i]); 15 for (int i = 1; i <= n; i++) 16 ans = max(ans, f[i]); 17 cout << ans; 18 return 0; 19 }
蓝桥杯 ALGO-32 JAM 计数法
问题描述:
Jam是个喜欢标新立异的科学怪人。他不使用阿拉伯数字计数,而是使用小写英文字母计数,他觉得这样做,会使世界更加丰富多彩。在他的计数法中,每个数字的位数都是相同的(使用相同个数的字母),英文字母按原先的顺序,排在前面的字母小于排在它后面的字母。我们把这样的“数字”称为Jam数字。在Jam数字中,每个字母互不相同,而且从左到右是严格递增的。每次,Jam还指定使用字母的范围,例如,从2到10,表示只能使用{b,c,d,e,f,g,h,i,j}这些字母。如果再规定位数为5,那么,紧接在Jam数字“bdfij”之后的数字应该是“bdghi”。(如果我们用U、V依次表示Jam数字“bdfij”与“bdghi”,则U<V< span>,且不存在Jam数字P,使U<P<V< span>)。你的任务是:对于从文件读入的一个Jam数字,按顺序输出紧接在后面的5个Jam数字,如果后面没有那么多Jam数字,那么有几个就输出几个。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 35 5 6 int l, r, n; 7 char a[MAXN]; 8 9 int main() { 10 cin >> l >> r >> n >> a + 1; 11 l += 'a' - 1, r += 'a' - 1; 12 for (int i = 1; i <= 5; i++) { 13 for (int j = n; j >= 1; j--) 14 if (a[j] != r + j - n) { 15 a[j]++; 16 int o = a[j]; 17 for (int k = j + 1; k <= n; k++) 18 a[k] = ++o; 19 break; 20 } 21 for (int j = 1; j <= n; j++) 22 cout << a[j]; 23 cout << endl; 24 } 25 return 0; 26 }
蓝桥杯 ALGO-33 数列
问题描述:
给定一个正整数k(3≤k≤15),把所有k的方幂及所有有限个互不相等的k的方幂之和构成一个递增的序列,例如,当k=3时,这个序列是:
1,3,4,9,10,12,13,…
(该序列实际上就是:30,31,30+31,32,30+32,31+32,30+31+32,…)
请你求出这个序列的第N项的值(用10进制数表示)。
例如,对于k=3,N=100,正确答案应该是981。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 long long k, n, x, o, ans; 5 6 int main() { 7 cin >> k >> n; 8 for (o = 1; o <= n; o <<= 1, x++); 9 o >>= 1; 10 while (n) { 11 if (n >= o) n -= o, ans += pow(k, x - 1); 12 o >>= 1, x--; 13 } 14 cout << ans; 15 return 0; 16 }
(代码是正确的,但并不能在蓝桥杯 OJ 上 AC,下载了数据后发现是 OJ 上的第 10 个数据点的答案有问题,可以忽视)
蓝桥杯 ALGO-34 纪念品分组
问题描述:
元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得的纪念品价值 相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品,并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时 间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 30005 5 6 int mx, n, a[MAXN], l, r, ans; 7 8 int main() { 9 cin >> mx >> n; 10 for (int i = 1; i <= n; i++) 11 cin >> a[i]; 12 l = 1, r = n; 13 sort(a + 1, a + n + 1); 14 while (l < r) { 15 if (a[l] + a[r] <= mx) l++, ans++; 16 else if (a[r] <= mx) ans++; 17 r--; 18 } 19 ans += l == r && a[l] <= mx; 20 cout << ans; 21 return 0; 22 }
蓝桥杯 ALGO-35 传球问题
问题描述:
上体育课的时候,小蛮的老师经常带着同学们一起做游戏。这次,老师带着同学们一起做传球游戏。
游戏规则是这样的:n个同学站成一个圆圈,其中的一个同学手里拿着一个球,当老师吹哨子时开始传球,每个同学可以把球传给自己左右的两个同学中的一个(左右任意),当老师再次吹哨子时,传球停止
此时,拿着球没传出去的那个同学就是败者,要给大家表演一个节目。
聪明的小蛮提出一个有趣的问题:有多少种不同的传球方法可以使得从小蛮手里开始传的球,传了m次以后,又回到小蛮手里。两种传球的方法被视作不同的方法,当且仅当这两种方法中,接到球的同学按接球顺序组成的序列是不同的。比如有3个同学1号、2号、3号,并假设小蛮为1号,球传了3次回到小蛮手里的方式有1->2->3->1和1->3->2->1,共2种。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 105 5 6 int n, m, f[MAXN][MAXN]; 7 8 int main() { 9 cin >> n >> m; 10 f[0][0] = 1; 11 for (int i = 1; i <= m; i++) 12 for (int j = 0; j < n; j++) 13 f[i][j] = f[i - 1][(j - 1 + 2 * n) % n] + f[i - 1][(j + 1) % n]; 14 cout << f[m][0]; 15 return 0; 16 }
蓝桥杯 ALGO-36 传纸条
问题描述:
小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题。一次素质拓展活动中,班上同学安排做成一个m行n列的矩阵,而小渊和小轩被安排在矩阵对角线的两端,因此,他们就无法直接交谈了。幸运的是,他们可以通过传纸条来进行交流。纸条要经由许多同学传到对方手里,小渊坐在矩阵的左上角,坐标(1,1),小轩坐在矩阵的右下角,坐标(m,n)。从小渊传到小轩的纸条只可以向下或者向右传递,从小轩传给小渊的纸条只可以向上或者向左传递。
在活动进行中,小渊希望给小轩传递一张纸条,同时希望小轩给他回复。班里每个同学都可以帮他们传递,但只会帮他们一次,也就是说如果此人在小渊递给小轩纸条的时候帮忙,那么在小轩递给小渊的时候就不会再帮忙。反之亦然。
还有一件事情需要注意,全班每个同学愿意帮忙的好感度有高有低(注意:小渊和小轩的好心程度没有定义,输入时用0表示),可以用一个0-100的自然数来表示,数越大表示越好心。小渊和小轩希望尽可能找好心程度高的同学来帮忙传纸条,即找到来回两条传递路径,使得这两条路径上同学的好心程度只和最大。现在,请你帮助小渊和小轩找到这样的两条路径。
代码:
#include <bits/stdc++.h> using namespace std; #define MAXN 55 int n, m, a[MAXN][MAXN], f[MAXN][MAXN][MAXN][MAXN]; int main() { cin >> n >> m; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) cin >> a[i][j]; for (int i = 1; i <= n; i++) for (int j = 1; j <= m; j++) for (int k = 1; k <= n; k++) for (int l = 1; l <= m; l++) { if (i == k || j == l) continue; f[i][j][k][l] = max(max(f[i - 1][j][k - 1][l], f[i - 1][j][k][l - 1]), max(f[i][j - 1][k - 1][l], f[i][j - 1][k][l - 1])) + a[i][j] + a[k][l]; } cout << f[n][m - 1][n - 1][m]; return 0; }
蓝桥杯 ALGO-37 Hankson 的趣味题
问题描述:
Hanks 博士是 BT (Bio-Tech,生物技术) 领域的知名专家,他的儿子名叫Hankson。现 在,刚刚放学回家的Hankson 正在思考一个有趣的问题。 今天在课堂上,老师讲解了如何求两个正整数 c1 和 c2 的最大公约数和最小公倍数。现 在Hankson 认为自己已经熟练地掌握了这些知识,他开始思考一个“求公约数”和“求公倍数”之类问题的“逆问题”,这个问题是这样的:已知正整数 a0,a1,b0,b1,设某未知正整数 x 满足: 1. x 和 a0 的最大公约数是 a1 ; 2. x 和b0 的最小公倍数是b1。 Hankson 的“逆问题”就是求出满足条件的正整数x。但稍加思索之后,他发现这样的 x 并不唯一,甚至可能不存在。因此他转而开始考虑如何求解满足条件的 x 的个数。请你帮 助他编程求解这个问题。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int t, a, b, c, d; 5 6 int gcd(int x, int y) { 7 return y ? gcd(y, x % y) : x; 8 } 9 10 int main() { 11 cin >> t; 12 for (int j = 1; j <= t; j++) { 13 cin >> a >> b >> c >> d; 14 int p = a / b, q = d / c, ans = 0; 15 for (int x = 1; x * x <= d; x++) 16 if (d % x == 0) { 17 ans += x % b == 0 && gcd(x / b, p) == 1 && gcd(q, d / x) == 1; 18 int y = d / x; 19 if (x == y) continue; 20 ans += y % b == 0 && gcd(y / b, p) == 1 && gcd(q, d / y) == 1; 21 } 22 cout << ans << endl; 23 } 24 return 0; 25 }
(x 必然不会超过 d,直接枚举就行了,想半天没想出这么简单的办法 = =)
蓝桥杯 ALGO-38 接水问题
问题描述:
学校里有一个水房,水房里一共装有 m 个龙头可供同学们打开水,每个龙头每秒钟的 供水量相等,均为1。 现在有n 名同学准备接水,他们的初始接水顺序已经确定。将这些同学按接水顺序从 1 到 n 编号,i 号同学的接水量为 wi。接水开始时,1 到 m 号同学各占一个水龙头,并同时打开水龙头接水。当其中某名同学j 完成其接水量要求 wj 后,下一名排队等候接水的同学 k 马上接替 j 同学的位置开始接水。这个换人的过程是瞬间完成的,且没有任何水的浪费。即 j 同学第 x 秒结束时完成接水,则 k 同学第 x + 1 秒立刻开始接水。若当前接水人数 n’ 不足 m, 则只有 n’ 个龙头供水,其它 m − n’ 个龙头关闭。 现在给出 n 名同学的接水量,按照上述接水规则,问所有同学都接完水需要多少秒。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 10005 5 6 int n, m, a[MAXN], b[MAXN], x, o, ans; 7 8 9 int main() { 10 cin >> n >> m; 11 for (int i = 1; i <= n; i++) 12 cin >> a[i]; 13 o = m; 14 for (int i = 1; i <= m; i++) 15 b[i] = a[i]; 16 while (x != m) { 17 x = 0, ans++; 18 for (int i = 1; i <= m; i++) { 19 if (b[i]) b[i]--; 20 if (!b[i]) 21 if (o != n) b[i] = a[++o]; 22 else x++; 23 } 24 } 25 cout << ans; 26 return 0; 27 }
蓝桥杯 ALGO-39 数组排序去重
问题描述:
输入 10 个整数组成的序列,要求对其进行升序排序,并去掉重复元素。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int a[11]; 5 6 int main() { 7 a[0] = -1 << 30; 8 for (int i = 1; i <= 10; i++) 9 cin >> a[i]; 10 sort(a + 1, a + 11); 11 unique(a + 1, a + 11); 12 for (int i = 1; a[i - 1] < a[i]; i++) 13 cout << a[i] << endl; 14 return 0; 15 }
蓝桥杯 ALGO-40 会议中心
?
蓝桥杯 ALGO-41 【无】
蓝桥杯 ALGO-42 送分啦
蓝桥杯 ALGO-43 A + B Problem
(凑题大法好??)
蓝桥杯 ALGO-44 采油区域
[题目][APIO2009][蓝桥杯ALGO-44] 采油区域
蓝桥杯 ALGO-45 调和数列问题
问题描述:
输入一个实数 x,求最小的 n 使得,1 / 2 + 1 / 3 + 1 / 4 + ... + 1 / (n + 1) >= x。
输入的实数 x 保证大于等于 0.01,小于等于 5.20,并且恰好有两位小数。你的程序要能够处理多组数据,即不停地读入 x,如果 x 不等于 0.00,则计算答案,否则退出程序。
输出格式为对于一个 x,输出一行 n card(s)。其中 n 表示要计算的答案。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 double x, o; 5 int n; 6 7 int main() { 8 while (1) { 9 cin >> x; 10 if (!x) exit(0); 11 o = 0; 12 for (n = 2; o < x; n++) o += 1.0 / (double)n; 13 cout << n - 2 << " card(s)" << endl; 14 } 15 return 0; 16 }
蓝桥杯 ALGO-46 Hanoi 问题
问题描述:
如果将课本上的Hanoi塔问题稍做修改:仍然是给定N只盘子,3根柱子,但是允许每次最多移动相邻的M只盘子(当然移动盘子的数目也可以小于M),最少需要多少次?
例如N=5,M=2时,可以分别将最小的2个盘子、中间的2个盘子以及最大的一个盘子分别看作一个整体,这样可以转变为N=3,M=1的情况,共需要移动7次。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int ans, m, n; 5 6 void move(int n, int m) { 7 if (n <= m) ans++; 8 else { 9 move(n - m, m); 10 ans++; 11 move(n - m, m); 12 } 13 } 14 15 int main() { 16 cin >> n >> m; 17 move(n, m); 18 cout << ans << endl; 19 return 0; 20 }
蓝桥杯 ALGO-47 蜜蜂飞舞
问题描述:
“两只小蜜蜂呀,飞在花丛中呀……”
话说这天天上飞舞着两只蜜蜂,它们在跳一种奇怪的舞蹈。用一个空间直角坐标系来描述这个世界,那么这两只蜜蜂初始坐标分别为(x1,y1,z1),(x2,y2,z2) 。在接下来它们将进行n次飞行,第i次飞行两只蜜蜂分别按照各自的速度向量飞行ti个单位时间。对于这一现象,玮玮已经观察了很久。他很想知道在蜜蜂飞舞结束时,两只蜜蜂的距离是多少。现在他就求教于你,请你写一个程序来帮他计算这个结果。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int n; 5 double vx1, vy1, vz1, vx2, vy2, vz2, t; 6 double tx1, ty1, tz1, tx2, ty2, tz2; 7 double x1, y11, z1, x2, y2, z2; 8 9 double dis(double x1, double y1, double z1, double x2, double y2, double z2) { 10 return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2) + (z1 - z2) * (z1 - z2)); 11 } 12 13 int main() { 14 cin >> n; 15 for (int i = 1; i <= n; i++) { 16 cin >> vx1 >> vy1 >> vz1 >> vx2 >> vy2 >> vz2 >> t; 17 tx1 += vx1 * t, ty1 += vy1 * t, tz1 += vz1 * t; 18 tx2 += vx2 * t, ty2 += vy2 * t, tz2 += vz2 * t; 19 } 20 cin >> x1 >> y11 >> z1 >> x2 >> y2 >> z2; 21 cout << fixed << setprecision(4) << dis(x1 + tx1, y11 + ty1, z1 + tz1, x2 + tx2, y2 + ty2, z2 + tz2); 22 return 0; 23 }
蓝桥杯 ALGO-50 数组查找及替换
问题描述:
给定某整数数组和某一整数b。要求删除数组中可以被b整除的所有元素,同时将该数组各元素按从小到大排序。如果数组元素数值在A到Z的ASCII之间,替换为对应字母。元素个数不超过100,b在1至100之间。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 105 5 6 int n, m, o, a[MAXN]; 7 8 int main() { 9 cin >> n >> m; 10 for (int i = 1; i <= n; i++) { 11 cin >> a[++o]; 12 if (a[o] % m == 0) o--; 13 } 14 sort(a + 1, a + o + 1); 15 for (int i = 1; i <= o; i++) 16 if (a[i] >= 'A' && a[i] <= 'Z') cout << (char)a[i] << ' '; 17 else cout << a[i] << ' '; 18 return 0; 19 }
蓝桥杯 ALGO-52 排列问题
问题描述:
求一个0~N-1的排列(即每个数只能出现一次),给出限制条件(一张N*N的表,第i行第j列的1或0,表示为j-1这个数不能出现在i-1这个数后面,并保证第i行第i列为0),将这个排列看成一个自然数,求从小到大排序第K个排列。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 15 5 6 int a[MAXN], n, k, vis[MAXN], f[MAXN][MAXN], cnt; 7 8 void getp(int o) { 9 if (o > n) { 10 cnt++; 11 if (cnt == k) { 12 for (int i = 1; i <= n; i++) 13 cout << a[i] << ' '; 14 exit(0); 15 } 16 return; 17 } 18 for (int i = 0; i < n; i++) { 19 int nob = 0; 20 if (!vis[i] && f[a[o - 1]][i] || o == 1) { 21 a[o] = i, vis[i] = 1; 22 getp(o + 1); 23 vis[i] = 0; 24 } 25 } 26 } 27 28 int main() { 29 cin >> n >> k; 30 for (int i = 0; i < n; i++) 31 for (int j = 0; j < n; j++) 32 cin >> f[i][j]; 33 getp(1); 34 return 0; 35 }
蓝桥杯 ALGO-54 简单加法(基本型)
问题描述:
首先给出简单加法算式的定义:
如果有一个算式(i)+(i+1)+(i+2),(i>=0),在计算的过程中,没有任何一个数位出现了进位,则称其为简单的加法算式。
例如:i=3时,3+4+5=12,有一个进位,因此3+4+5不是一个简单的加法算式;又如i=112时,112+113+114=339,没有在任意数位上产生进位,故112+113+114是一个简单的加法算式
问题:给定一个正整数n,问当i大于等于0且小于n时,有多少个算式(i)+(i+1)+(i+2)是简单加法算式。其中n<10000。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 int n, ans; 5 6 int getc(int o) { 7 int res = 0; 8 for (int i = 1; i <= 4; i++) 9 res += o % 10, o /= 10; 10 return res; 11 } 12 13 int main() { 14 cin >> n; 15 for (int i = 0; i < n; i++) 16 ans += getc(i) + getc(i + 1) + getc(i + 2) == getc(3 * i + 3); 17 cout << ans; 18 return 0; 19 }
蓝桥杯 ALGO-55 排列问题
问题描述:
给定两个N×M的矩阵,计算其和。其中:
N和M大于等于1且小于等于100,矩阵元素的绝对值不超过1000。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 105 5 6 int n, m, o, a[MAXN][MAXN]; 7 8 int main() { 9 cin >> n >> m; 10 for (int i = 1; i <= n; i++) 11 for (int j = 1; j <= m; j++) 12 cin >> a[i][j]; 13 for (int i = 1; i <= n; i++) { 14 for (int j = 1; j <= m; j++) 15 cin >> o, cout << a[i][j] + o << ' '; 16 cout << endl; 17 } 18 return 0; 19 }
蓝桥杯 ALGO-56 邮票
问题描述:
给定一个信封,有N(1≤N≤100)个位置可以贴邮票,每个位置只能贴一张邮票。我们现在有M(M<=100)种不同邮资的邮票,面值为X1,X2….Xm分(Xi是整数,1≤Xi≤255),每种都有N张。
显然,信封上能贴的邮资最小值是min(X1, X2, …, Xm),最大值是 N*max(X1, X2, …, Xm)。由所有贴法得到的邮资值可形成一个集合(集合中没有重复数值),要求求出这个集合中是否存在从1到某个值的连续邮资序列,输出这个序列的最大值。
例如,N=4,M=2,面值分别为4分,1分,于是形成1,2,3,4,5,6,7,8,9,10,12,13,16的序列,而从1开始的连续邮资序列为1,2,3,4,5,6,7,8,9,10,所以连续邮资序列的最大值为10分。
代码:
1 #include <bits/stdc++.h> 2 using namespace std; 3 4 #define MAXN 100005 5 6 int n, m, o, a[MAXN], f[MAXN]; 7 8 int main() { 9 cin >> n >> m; 10 for (int i = 1; i <= m; i++) 11 cin >> a[i]; 12 while (1) { 13 o++; 14 for (int i = 1; i <= m; i++) 15 if (o >= a[i]) 16 if (!f[o] || f[o] > f[o - a[i]] + 1) 17 f[o] = f[o - a[i]] + 1; 18 if (!f[o] || f[o] > n) 19 cout << o - 1, exit(0); 20 } 21 return 0; 22 }
蓝桥杯 ALGO-52 排列问题
问题描述:
求一个0~N-1的排列(即每个数只能出现一次),给出限制条件(一张N*N的表,第i行第j列的1或0,表示为j-1这个数不能出现在i-1这个数后面,并保证第i行第i列为0),将这个排列看成一个自然数,求从小到大排序第K个排列。
代码: