第九届蓝桥杯题解 2022/3/8
第九届蓝桥杯题解
本应该是上周就发出来的,前几天考试,鸽了两天
(生产队的驴也不敢这么休息吧)
鬼灭之刃真好看(划去)
分数
很简单的一道签到题,其实不用程序算,可以直接用等比数列算一下,然后让程序约一下分就好
1 |
|
星期一
看一下日历,年末最后一天是星期天,直接设置以7为周期的循环,找到几是几
1 |
|
乘积尾零
读入一个数据后,统计其5和2的因数,到最后统计5和2的个数,取最小即可
1 |
|
第几个幸运数
筛查目标数字的方法很巧妙
直接用stl的set来做,会简单很多
注意一下set的用法,stl用好了可以省很多事 (用的不好会多很多事)
1 |
|
航班时间
一道模拟题,读取数据用到一个sscanf,可以省很多事,在做天梯赛的字符串处理可以大杀四方
1 |
|
二刷的新写法
1 |
|
三体攻击
这道题真的写吐血了,差分当时只会一维的,临时含泪学了二维三维,具体思路直接看代码注释
首先我们可以分析一下,想要随时对三维数据进行加减更新,线段树不是首选(**多维线段树咱也不会**),我们考虑三维差分来维护数据,但是如何找到具体是哪一次攻击造成第一艘战舰的削减?我们考虑用二分查找,来查找造成削减的攻击。
注意事项
- 三维差分数组肯定不能开三维数组,我们考虑一维优化
- 我的代码在acwing可以ac(好像样例对就可以ac?数据有点水)蓝桥杯官网提交是83分,六个过五个,最后一个样例想过必须在二分上作文章,我的二分是每次将数组清零,重新搜,数据一大就超时了
- 尽量用scanf读数据,我cin输入没清缓存的话只有64分,清一下就83分了,最后一个数据靠读数据是没办法了(快读试了没用),只能在查找上做文章。
- ac代码(二分Pro)(我学不来)
- acwing上的数据有点水,想测一下到底能不能过尽量去蓝桥杯官网跑一下官网题目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
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
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using namespace std;
// 传送门:http://lx.lanqiao.cn/problem.page?gpid=T2724
// 三维差分(一维优化)+二分
int A, B, C, m;
int cha[maxn]; //差分数组
int a[maxn]; //通过差分数组还原的原数组
int instead[maxn];
struct node
{
int sa, sb, sc, ea, eb, ec;
int cost;
} query[maxn];
int get_pos(int a,int b,int c)
{
return a * B * C + b * C + c; //将三维坐标优化成一维存储(该数字是第a*B*C+b*C+c个,保证一一对应)
}
bool check(int num)
{
memset(a, 0, sizeof(0));
memcpy(instead, cha, sizeof(cha));
// for (int i = 1; i <= A; i++)
// for (int j = 1; j <= B; j++)
// for (int k = 1; k <= C; k++)
// cout << instead[get_pos(i, j, k)];
// cout << endl;
for (int i = 1; i <= num; i++)
{
int x1 = query[i].sa;
int x2 = query[i].ea;
int y1 = query[i].sb;
int y2 = query[i].eb;
int z1 = query[i].sc;
int z2 = query[i].ec;
int remp = query[i].cost;
instead[get_pos(x1, y1, z1)] -= remp;
instead[get_pos(x1, y1, z2 + 1)] += remp;
instead[get_pos(x1, y2 + 1, z1)] += remp;
instead[get_pos(x2 + 1, y1, z1)] += remp;
instead[get_pos(x1, y2 + 1, z2 + 1)] -= remp;
instead[get_pos(x2 + 1, y1, z2 + 1)] -= remp;
instead[get_pos(x2 + 1, y2 + 1, z1)] -= remp;
instead[get_pos(x2 + 1, y2 + 1, z2 + 1)] += remp;
}
for (int i = 1; i <= A; i++)
for (int j = 1; j <= B; j++)
for (int k = 1; k <= C; k++)
{
a[get_pos(i, j, k)] = (a[get_pos(i, j, k - 1)] + a[get_pos(i, j - 1, k)] + a[get_pos(i - 1, j, k)]) - (a[get_pos(i - 1, j - 1, k)] + a[get_pos(i - 1, j, k - 1)] + a[get_pos(i, j - 1, k - 1)]) + a[get_pos(i - 1, j - 1, k - 1)] + instead[get_pos(i, j, k)];
// cout << a[get_pos(i, j, k)] << ' ';
if (a[get_pos(i, j, k)] < 0)
return true;
}
return false;
}
int main()
{
// ios::sync_with_stdio(false);
cin >> A >> B >> C >> m;
for (int i = 1; i <= A; i++)
for (int j = 1; j <= B; j++)
for (int k = 1; k <= C; k++)
{
int remp;
cin >> remp;
//开始更新差分数组
cha[get_pos(i, j, k)] += remp;
cha[get_pos(i + 1, j, k)] -= remp;
cha[get_pos(i, j + 1, k)] -= remp;
cha[get_pos(i, j, k + 1)] -= remp;
cha[get_pos(i + 1, j + 1, k)] += remp;
cha[get_pos(i + 1, j, k + 1)] += remp;
cha[get_pos(i, j + 1, k + 1)] += remp;
cha[get_pos(i + 1, j + 1, k + 1)] -= remp;
}
// for (int i = 1; i <= A; i++)
// for (int j = 1; j <= B; j++)
// for (int k = 1; k <= C; k++)
// cout << cha[get_pos(i, j, k)];
// cout << endl;
for (int i = 1; i <= m; i++)
{
cin >> query[i].sa >> query[i].ea >> query[i].sb >> query[i].eb >> query[i].sc >> query[i].ec >> query[i].cost;
}
int l = 1, r = m, ans;
while (l <= r)
{
int mid = (l + r) >> 1;
if (check(mid))
{
// cout << "true" << endl;
ans = mid;
r = mid - 1; //有战舰击毁,区间向左压缩
}
else
{
l = mid + 1; //没有战舰被击毁。区间向右压缩
// cout << "false" << endl;
}
}
cout << ans;
return 0;
}全球变暖
dfs+连通块,每次搜到陆地直接把这一个岛直接搜完,开个数组记录有没有被淹,到最后统计一下就行二刷后的新写法,更清晰了一些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
using namespace std;
// 传送门:http://lx.lanqiao.cn/problem.page?gpid=T2725
// 深搜+连通块
int N;
int edge[maxn][maxn];
bool visit[maxn][maxn];
int dirx[4] = {0, 0, -1, 1};
int diry[4] = {-1, 1, 0, 0};
int num; //记录大陆个数
int ans_num; //记录未被淹没的海岛个数
int ans[maxn]; // ans[i]记录第i个大陆剩余的岛屿
void search(int x, int y)
{
if (visit[x][y] == 1 || edge[x][y] == 0)
return;
visit[x][y] = 1;
bool flag = 1;
for (int i = 0; i < 4; i++)
{
int rempy = y + diry[i];
int rempx = x + dirx[i];
if (edge[rempx][rempy] == 0)
flag = 0;
}
if (edge[x][y] == 1 && flag == 1)
ans[num]++;
for (int i = 0; i < 4; i++)
{
int rempy = y + diry[i];
int rempx = x + dirx[i];
search(rempx, rempy);
}
}
int main()
{
ios::sync_with_stdio(false);
cin >> N;
for (int i = 1; i <= N; i++)
{
string remp;
cin >> remp;
for (int j = 0; j < N; j++)
{
if (remp[j] == '.')
{
edge[i][j + 1] = 0;
}
else
{
edge[i][j + 1] = 1;
}
}
}
for (int i = 1; i <= N; i++)
{
for (int j = 1; j <= N; j++)
{
if (edge[i][j] == 1 && visit[i][j] == 0)
{
num++;
// cout << i << " " << j << endl;
search(i, j);
if (ans[num])
ans_num++;
}
}
}
cout << num - ans_num;
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
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
using namespace std;
int maze[1010][1010];
bool visit[1010][1100];
int num; //原
int ans_num; //剩
int n;
int ans;
bool judge;
int dirx[4] = {0, 0, -1, 1};
int diry[4] = {1, -1, 0, 0};
void dfs(int x, int y)
{
if (visit[x][y] == true || maze[x][y] == 0)
return;
visit[x][y] = 1;
bool flag = true;
for (int i = 0; i < 4; i++)
{
int rempx = dirx[i] + x;
int rempy = diry[i] + y;
if (maze[rempx][rempy] == 0)
flag = false;
}
if (flag)
judge = true;
for (int i = 0; i < 4; i++)
{
int rempx = dirx[i] + x;
int rempy = diry[i] + y;
dfs(rempx, rempy);
}
}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
char remp[10000];
cin >> remp;
for (int j = 0; j < n; j++)
{
if (remp[j] == '.')
maze[i][j + 1] = 0;
else
maze[i][j + 1] = 1;
}
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (maze[i][j] == 0)
continue;
if (visit[i][j])
continue;
judge = false;
dfs(i, j);
num++;
if (judge)
ans_num++;
}
}
cout << num - ans_num;
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
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
using namespace std;
// http://lx.lanqiao.cn/problem.page?gpid=T2726
// 余数处理+贪心
vector<long long> a[maxn];
long long ans = 0;
long long n, k;
int main()
{
cin >> n >> k;
long long remp;
for (int i = 1; i <= n; i++)
{
cin >> remp;
a[remp % k].push_back(remp);
}
for (int i = 0; i < k; i++)
{
sort(a[i].begin(), a[i].end(), greater<long long>());
// cout << a[i][0] << endl;
}
for (long long i = 0; i < k; i++)
for (long long j = 0; j < k; j++)
{
long long t = (k - (i + j) % k) % k; //仍然要取余,k-i-j可能是负数,负数取余还是负数!达不到效果
long long sum = 0;
if (a[i].size() && a[j].size() && a[t].size())
{
if (i != j && j != t && i != t)
{
sum = a[i][0] + a[j][0] + a[t][0];
}
if (i == j && j != t && i != t)
{
if (a[i].size() == 1)
continue; //假如以i为余数里面只有一个,不够用
sum = a[i][0] + a[i][1] + a[t][0];
}
if (i == t && i != j && t != j)
{
if (a[i].size() == 1)
continue;
sum = a[i][0] + a[i][1] + a[j][0];
}
if (j == t && i != j && t != i)
{
if (a[j].size() == 1)
continue;
sum = a[j][0] + a[j][1] + a[i][0];
}
if (i == j && j == t && t == i)
{
if (a[i].size() < 3)
continue;
sum = a[j][0] + a[j][1] + a[j][2];
}
}
ans = max(sum, ans);
}
cout << ans;
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
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
using namespace std;
vector<long long>a[1010];
long long sum=0;
long long n,k;
int main()
{
cin>>n>>k;
for(int i=1;i<=n;i++)
{
long long remp;
cin>>remp;
a[remp%k].push_back(remp);
// cout<<remp<<" "<<k<<" "<<remp%k<<endl;
}
for(int i=0;i<k;i++)
{
sort(a[i].begin(),a[i].end(),greater<long long>());
}
for(long long i=0;i<k;i++)
for(long long j=0;j<k;j++)
{
long long z=(k-(i+j)%k)%k;
// cout<<z<<endl;
// cout<<a[i].size()<<" "<<a[j].size()<<" "<<a[z].size()<<endl;
if(a[i].size()&&a[j].size()&&a[z].size())
{
// cout<<endl;
if(i!=j&&i!=z&&j!=z)
{
sum=max(sum,a[i][0]+a[j][0]+a[z][0]);
// cout<<a[i][0]+a[j][0]+a[z][0]<<endl;
}
if(i==j&&j!=z&&i!=z)
{
if(a[i].size()<2)
continue;
sum=max(sum,a[i][0]+a[j][1]+a[z][0]);
// cout<<a[i][0]+a[j][1]+a[z][0]<<endl;
}
if(i==z&&i!=j&&j!=z)
{
if(a[i].size()<2)
continue;
sum=max(sum,a[i][0]+a[i][1]+a[j][0]);
// cout<<a[i][0]+a[i][1]+a[j][0]<<endl;
}
if(j==z&&i!=j&&i!=z)
{
if(a[j].size()<2)
continue;
sum=max(sum,a[j][0]+a[j][1]+a[i][0]);
// cout<<a[j][0]+a[j][1]+a[i][0]<<endl;
}
if(i==j&&j==z&&i==z)
{
if(a[i].size()<3)
continue;
sum=max(sum,a[i][0]+a[i][1]+a[i][2]);
// cout<<a[i][0]+a[i][1]+a[i][2]<<endl;
}
}
}
cout<<sum;
return 0;
}
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment