分类

入门

判断闰年

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
/*
.判断闰年。闰年有两种情况:
(1) 能被100整除时,必须能被400整除;
(2) 不能被100整除时,被4整除即可。
*/
#include <iostream>
#include <cstdio>

using namespace std;

int main()
{
int year;
cin >> year;

if (year % 100 == 0)
{
if (year % 400 == 0) cout << "yes" << endl;
else cout << "no" << endl;
}
else
{
if (year % 4 == 0) cout << "yes" << endl;
else cout << "no" << endl;
}

return 0;
}

明明的随机数

题目链接:[P1059 NOIP2006 普及组] 明明的随机数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

P.S.代码

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;

const int N = 1010;

int q[N], sum;

int main()
{

int n, x;
cin >> n;
for(int i = 0; i < n; i++)
{
scanf("%d", &x);
if(q[x]) continue;
q[x]++;
sum++;
}
cout << sum << endl;
for(int i = 0; i <= 1000; i++)
if(q[i]) cout << i << ' ';
cout << endl;


return 0;
}

排序

快速排序

题目链接P1177 【模板】快速排序 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

思路:核心思想是分治,数组中找一个数作为分界点x, 小于x的放左边, 大于x的放右边, 化成两个区域, 再递归处理左右两段, 要注意边界问题

P.S. 代码:

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 <iostream>

using namespace std;

const int N = 100010;
int q[N], n;

void quick_sort(int l, int r){
if(l >= r) return;

int i = l - 1, j = r + 1, x = q[l + r >> 1];
while(i < j){
while(q[++i] < x);
while(q[--j] > x);
if(i < j) swap(q[i], q[j]);
}
quick_sort(l, j), quick_sort(j + 1, r);

}

int main(){

scanf("%d", &n);
for(int i = 0; i < n; i++) scanf("%d", &q[i]);
quick_sort(0, n - 1);
for(int i = 0; i < n; i++) printf("%d ", q[i]);
return 0;
}

二维差分

题目链接:P3397 地毯 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

二维差分实际上就是差分 + 子矩阵和

子矩阵和的公式是:

image-20230405163914803

差分公式:

image-20230405164033210

解题思路:

先构造出二维差分矩阵

1
2
3
4
5
6
7
void insert(int x1, int y1, int x2, int y2, int c)
{
b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
}

image-20230405165829989

再求出子矩阵和即可

1
2
3
b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];//二维前缀和
//其实这里的b[i][j]就是a[i][j]
//原公式二维前缀和:s[i][j] = s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1] + a[i][j];

详细差分内容可参考这篇博客

(9条消息) 【学习总结】一、二维前缀和 && 一、二维差分_吹往北方的风的博客-CSDN博客

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
#include <iostream>

using namespace std;

const int N = 1010;

int a[N][N], b[N][N];

void insert(int x1, int y1, int x2, int y2, int c)
{
b[x1][y1] += c;
b[x2 + 1][y1] -= c;
b[x1][y2 + 1] -= c;
b[x2 + 1][y2 + 1] += c;
}

int main()
{
int n, m;

cin >> m >> n;
for(int i = 1; i <= m; i++)
for(int j = 1; j <= m; j++)
a[i][j] = 0;

for(int i = 1; i <= m; i++)
for(int j = 1; j <= m; j++)
insert(i, j, i, j, 0);


while(n--)
{
int x1, x2, y1, y2, c;
cin >> x1 >> y1 >> x2 >> y2;
insert(x1, y1, x2, y2, 1);
}

for(int i = 1; i <= m; i++)
for(int j = 1; j <= m; j++)
b[i][j] += b[i - 1][j] + b[i][j - 1] - b[i - 1][j - 1];

for(int i = 1; i <= m; i++)
{
for(int j = 1; j <= m; j++) printf("%d ", b[i][j]);
printf("\n");
}

return 0;
}