第十届蓝桥杯真题
代码会在4.1号更新
1.组队
填空题,直接算即可
组队链接在这里
直接算:
2.年号字符
十进制转化为二十六进制
年号链接
代码:10进制转26进制
#include <cstring>
#include <algorithm>
using namespace std;
int main(){
int n = 2019;
string s;
while (n){
char c = n % 26 + 'A' - 1; // (-1)!!!
s += c;
n /= 26;
}
for (int i = s.size() - 1; i >= 0; i -- ) cout << s[i];
return 0;
}
3.数列求值
滚动数组
数列求值链接
代码:滚动数组
#include<iostream>
using namespace std;
int main()
{
int num[3] = {1, 1, 1};
int idx = 3; //idx是3,但是是从第四项开始的
while(idx <= 20190323) //不是20190324嗷
{
num[idx % 3] = num[0] + num[1] + num[2]; //三个为一组
num[idx % 3] %= 10000; //因为只需要保留最后四位
idx ++;
}
idx --;
printf("%d\n", num[idx % 3]);
return 0;
}
4.数的分解
暴力枚举
数的分解链接
代码:暴力枚举
#include <iostream>
#include <algorithm>
using namespace std;
bool check(int x){
while(x){
int ac = x % 10;
if(ac == 2 || ac == 4) return false;
x /= 10;
}
return true;
}
int main(){
int cnt = 0;
for (int i = 1; i <= 2019; i ++ ){
if(!check(i)) continue;
for (int j = i + 1; j < 2019 - i - j; j ++ ) //!!!
if(check(j) && check(2019 - i - j)) cnt ++;
}
printf("%d\n", cnt);
return 0;
}
5.迷宫
bfs
迷宫链接
代码: bfs
#include <bits/stdc++.h>
using namespace std;
int g[30][50], b[30][50];
int dx[4] = {1, 0, 0, -1}, dy[4] = {0, -1, 1, 0};
char ds[4] = {'D', 'L', 'R', 'U'};
void bfs(){
//因为有路径,所有连路径一起更新一起存
queue<pair<pair<int, int>, string>> q;
memset(b, -1, sizeof b);
b[0][0] = 0;
q.push({{0, 0}, ""});
while (!q.empty()){
auto t = q.front(); q.pop();
int l = t.first.first, r = t.first.second;
string s = t.second;
if(l == 29 && r == 49){
cout << s << endl;
break;
}
for (int i = 0; i < 4; i ++ ){
int x = l + dx[i], y = r + dy[i];
if(!g[x][y] && b[x][y] == -1 && x >= 0 && y >= 0 && x < 30 && y < 50){
b[x][y] = b[l][r] + 1;
q.push({{x, y}, s += ds[i]});
}
}
}
}
int main(){
for (int i = 0; i < 30; i ++ ){
string s; cin >> s;
for (int j = 0; j < 50; j ++ ) g[i][j] = s[j] - '0';
}
bfs(0, 0);
return 0;
}
后面题目会有两个链接,1是acwing的,2是其他网站的,acwing买了课才能写好像
6.特别的数
代码:暴力枚举
#include <iostream>
using namespace std;
bool check(int x){
while(x){
int m = x % 10;
x /= 10;
if(m == 2 || !m || m == 1 || m == 9) return true;
}
return false;
}
int main(){
int n; cin >> n;
long long ans = 0;
for (int i = 1; i <= n; i ++ ){
if(check(i)) ans += i;
}
printf("%d\n", ans);
return 0;
}
7.完全二叉树的权值
代码:双指针
#include <iostream>
using namespace std;
int main(){
int n; cin >> n;
long long ans = -1e18;
int cnt = 0, idx = 1;
for (int i = 1; i <= n; i *= 2 ){
long long res = 0;
for (int j = i; j < i * 2 && j <= n; j ++ ){
int x; cin >> x;
res += x;
}
if(ans < res) cnt = idx, ans = res;
idx ++;
}
printf("%lld\n", cnt);
return 0;
}
8.等差数列
代码:欧几里得
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int gcd(int a, int b){ //欧几里得算法
return b ? gcd(b, a % b) : a;
}
int main(){
int n; cin >> n;
vector<int> a(n);
for (int i = 0; i < n; i ++ ) cin >> a[i];
sort(a.begin(), a.end());
//找最小的差值的最大公约数
int ac = 0;
for (int i = 1; i < n; i ++ ){
if(i == 1) ac = a[i] - a[i - 1];
ac = gcd(a[i] - a[i - 1], ac);
}
if(!ac) printf("%d\n", n);
else printf("%d\n", a[n - 1] / ac - a[0] / ac + 1);
return 0;
}
9.后缀表达式
代码:贪心
#include <iostream>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;
const int N = 2e5 + 10;
int a[N];
int main(){
int n, m; cin >> n >> m;
int k = n + m + 1;
for (int i = 0; i < k; i ++ ) cin >> a[i];
sort(a, a + k);
long long ans = 0;
if(!m) for (int i = 0; i < k; i ++ ) ans += a[i];
else{
ans = a[k - 1] - a[0];
for (int i = 1; i < k - 1; i ++ ) ans += abs(a[i]);
}
printf("%lld\n", ans);
return 0;
}
10.灵能传输
代码:贪心+前缀和
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 3e5 + 10;
LL a[N], s[N];
bool st[N];
int main(){
int t; cin >> t;
while (t -- ){
int n; cin >> n;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
//计算前缀和
s[0] = 0; //必须赋初值,不然会乱赋值
for (int i = 1; i <= n; i ++ ) s[i] = s[i - 1] + a[i];
//记录s0和sn,因为a1和an不能传输灵能
LL s0 = s[0], sn = s[n];
if(s0 > sn) swap(s0, sn); //保证s0小于sn
sort(s, s + n + 1); //[0, n]
//排序后从前往后找s0,从后往前找sn的坐标(如果s0==sn就不会出错)
for (int i = 0; i <= n; i ++ ){
if(s[i] == s0){
s0 = i;
break;
}
}
for (int i = n; i >= 0; i -- ){
if(s[i] == sn){
sn = i;
break;
}
}
//然后开始距离的遍历:s0->min->(s0)->(sn)->max->sn;
memset(st, false, sizeof st);
int l = 0, r = n;
for (int i = s0; i >= 0; i -= 2 ) a[l ++] = s[i], st[i] = true;
for (int i = sn; i <= n; i += 2 ) a[r --] = s[i], st[i] = true;
for (int i = 0; i <= n; i ++ ) if(!st[i]) a[l ++] = s[i];
//遍历一波,距离最大的间距,即为最优的最小灵能(因为a[i] = s[i] - s[i - 1])
LL ans = 0;
for (int i = 1; i <= n; i ++ ) ans = max(ans, abs(a[i] - a[i - 1]));
printf("%lld\n", ans);
}
return 0;
}