第十一届蓝桥杯题解

注释:这段时间正好在写蓝桥杯的题,将部分的题目的解法和大家分享,代码中的网址是该代码蒟蒻当时参考其他大佬的题解文章所在的网址,鸣谢大佬,如有错误,欢迎各位大佬指正
有部分网址是提交答案的oj传送门

门牌制作

直接枚举即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include <bits/stdc++.h>
using namespace std;
// 传送门:http://oj.ecustacm.cn/problem.php?id=1508
int find(int n)
{
int a=0;
while(n)
{
if(n%10==2)
a++;
n/=10;
}
return a;
}
int main()
{
long long ans=0;
for(int i=1;i<=2020;i++)
{
ans+=find(i);
}
cout<<ans;
return 0;
}

既约分数

直接从头开始枚举即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <bits/stdc++.h>
using namespace std;
int gcd(int x,int y)
{
if(y!=0)
return gcd(y,x%y);
else
return x;
}
int main()
{
long long ans=0;
for(int i=1;i<=2020;i++)
for(int j=1;j<=2020;j++)
if(gcd(i,j)==1)
ans++;
cout<<ans;
return 0;
}

蛇形填数

一道很经典的题,很多oj上都有的练习题

1
2
3
4
5
6
7
8
9
10
11
12
#include <bits/stdc++.h>
using namespace std;
// http://oj.ecustacm.cn/problem.php?id=1510
int main()
{
int ans=1;

for(int i=1;i<=19;i++)
ans+=(i*4);
cout<<ans;
return 0;
}

或者直接用数学公式计算,算出通项公式

1
2
3
4
5
6
7
8
9
#include <bits/stdc++.h>
using namespace std;
// 规律:设a(n)是n行h列的元素, a(n)-a(n-1)=4*(n-1)
// a(n)=2*n*(n-1)+1
int main()
{
cout<<2*20*19+1;
return 0;
}

七段码

一道深搜回溯问题,首先用dfs(1)到dfs(7)利用回溯多层递归将所有的点亮方式枚举,然后在dfs(8)中对每一层的不同种情况进行judge判断即可
实质上是之前的递归将所有的可能情况进行罗列,在最后一层递归中进行判断

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include <bits/stdc++.h>
using namespace std;
// 传送门:http://oj.ecustacm.cn/problem.php?id=1511
// dfs+并查集+回溯
// 思路:首先用dfs(1)到dfs(7)利用回溯多层递归将所有的点亮方式枚举
// 然后在dfs(8)中对每一层的不同种情况进行judge判断即可
int edge[8][8];
int father[8]; //并查集数组
int use[8]; //判断是否点亮
void input()
{
edge[1][2] = edge[1][6] = 1;
edge[2][1] = edge[2][7] = edge[2][3] = 1;
edge[3][2] = edge[3][4] = edge[3][7] = 1;
edge[4][3] = edge[4][5] = 1;
edge[5][4] = edge[5][6] = edge[5][7] = 1;
edge[6][1] = edge[6][5] = edge[6][7] = 1;
}
int find(int x)
{
if (father[x] == x)
return x;
else
return father[x] = find(father[x]);
}
void connect(int x, int y)
{
father[find(x)] = father[find(y)];
}
int ans;
void judge()
{
for (int i = 1; i <= 7; i++)
father[i] = i;
for (int i = 1; i <= 7; i++)
for (int j = 1; j <= 7; j++)
{
if (edge[i][j] && use[i] && use[j])
{
int fa1 = find(i);
int fa2 = find(j);
if (fa1 != fa2)
{
connect(fa1, fa2);
}
}
}
int count = 0;
for (int i = 1; i <= 7; i++)
{
if (use[i] && father[i] == i)
count++;
}//将所有的亮灯都连起来,看看是不是相连
if (count == 1)
ans++;
return;
}
void dfs(int n)
{
if (n > 7)
{
judge();
return;
}
use[n] = 1;
dfs(n + 1);
use[n] = 0;
dfs(n + 1); //回溯!
}
int main()
{
input();
dfs(1);
cout << ans;
return 0;
}

回文数日期

呃,用了内置的函数,在c语言网上是ac的,但是蓝桥杯的官网直接编译错误,可能是蓝桥杯编译器版本问题,仅供参考

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
#include <bits/stdc++.h>
using namespace std;
// https://www.dotcpp.com/oj/problem2571.html
// 用到了C++自带的转换函数,在C语言网的oj能过,但是蓝桥杯的oj跑不了,嘛,当拓展思维了
int ji[13] = {0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
int run[13] = {0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
bool judge(string tar) //判断一个日期是否合法
{
string y = tar.substr(0, 4);
string m = tar.substr(4, 2);
string d = tar.substr(6, 2);
long long year, month, day;
if (!y.empty())
year = stoi(y);
if (!m.empty())
month = stoi(m);
if (!d.empty())
day = stoi(d);
if ((year % 100 != 0 && year % 4 == 0) || year % 400 == 0)
{
if (month <= 12 && month >= 1)
{
if (day <= run[month] && day >= 1)
return true;
else
return false;
}
else
return false;
}
else
{
if (month <= 12 && month >= 1)
{
if (day <= ji[month] && day >= 1)
return true;
else
return false;
}
else
return false;
}
}
int main()
{
ios::sync_with_stdio(false);
string now;
cin >> now;
int start2 = stoi(now.substr(0, 2));
int start1 = stoi(now.substr(0, 4));
for (int i = start1; i <= 9999; i++)
{

string front = to_string(i);
string after = front;
reverse(after.begin(), after.end());
string a = front + after;
if (a <= now)
continue;
if (judge(a))
{
cout << a << endl;
break;
}
}
for (int i = start2; i <= 99; i++)
{
string front = to_string(i);
string after = front;
reverse(after.begin(), after.end());
string a = front + front;
a += after;
a += after;
if (a <= now)
continue;
if (judge(a))
{
cout << a;
break;
}
}
// cout<<judge(now);
return 0;
}

成绩分析

按步模拟即可

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <bits/stdc++.h>
using namespace std;
// https://www.dotcpp.com/oj/problem2591.html
// 注意四舍五入的写法
// ans1 = lower_bound(a + 1, a + 1 + n, 85) - a-1;
// 后面要多减去1,因为数组从1开始存数
int a[10000];
int main()
{
int n;
cin >> n;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
sort(a + 1, a + 1 + n);
int ans1 = lower_bound(a + 1, a + 1 + n, 85) - a-1;
int ans2 = lower_bound(a + 1, a + n + 1, 60) - a-1;
double a1=n-ans1;
double a2=n-ans2;
a1=a1/n*100;
a2=a2/n*100;
a2=int(a2+0.5);
a1=int(a1+0.5);
cout<<a2<<"%"<<endl;
cout<<a1<<"%";
return 0;
}

平面分析

一道数学题,直接搬公式即可