高木さんBlog高木さん

Day5 备战CCF-CSP练习

高木さん·2024-10-12 08:59·12 次阅读

Day5 备战CCF-CSP练习

题目描述#

给定 n 个不同的整数,问这些数中有多少对整数,它们的值正好相差 1

输出格式#

输入的第一行包含一个整数 n,表示给定整数的个数。

第二行包含所给定的n 个整数。

输出格式#

输出一个整数,表示值正好相差 1 的数对的个数。

数据范围#

1n1000,给定的整数为不超过 10000 的非负整数。

输入样例:#

Copy
6 10 2 6 3 7 8

输出样例:#

Copy
3

样例解释#

值正好相差 1 的数对包括 (2,3),(6,7),(7,8)

题目分析#

语法题

C++代码#

Copy
#include <bits/stdc++.h> using namespace std; const int N = 1010; int n; int a[N]; int res = 0; int main() { cin >> n; for(int i = 0 ; i < n ; i ++) cin >> a[i]; for(int i = 0 ; i < n ; i ++) for(int j = i + 1 ; j < n ; j ++) if(abs(a[i] - a[j]) == 1) res ++ ; cout << res << '\n'; return 0; }

题目描述#

在一个定义了直角坐标系的纸上,画一个 (x1,y1)(x2,y2)的矩形指将横坐标范围从 x1x2,纵坐标范围从 y1y2 之间的区域涂上颜色。

下图给出了一个画了两个矩形的例子。

第一个矩形是 (1,1)(4,4),用绿色和紫色表示。

第二个矩形是 (2,3)(6,5),用蓝色和紫色表示。

图中,一共有 15 个单位的面积被涂上颜色,其中紫色部分被涂了两次,但在计算面积时只计算一次。

在实际的涂色过程中,所有的矩形都涂成统一的颜色,图中显示不同颜色仅为说明方便。

p21

给出所有要画的矩形,请问总共有多少个单位的面积被涂上颜色。

输入格式#

输入的第一行包含一个整数 n,表示要画的矩形的个数。

接下来 n 行,每行 4个非负整数,分别表示要画的矩形的左下角的横坐标与纵坐标,以及右上角的横坐标与纵坐标。

输出格式#

输出一个整数,表示有多少个单位的面积被涂上颜色。

数据范围#

1n100,0100

输入样例:#

Copy
2 1 1 4 4 2 3 6 5

输出样例:#

Copy
15

题目分析#

暴力/二维前缀和
暴力就不说了,讲一下优化

二位前缀和,我们将矩形中每一个点都当成前缀和的点,那么,我们只需要将顶点标注一下,就可以利用前缀和的性质画出整个矩形

如图一,蓝色是要画的目标矩形
屏幕截图 2024-09-24 201845.png

那么怎么构建差分数组呢
根据前缀和公式f[i][j] = f[i][j - 1] + f[i - 1][j] - f[i - 1][j - 1] + a[i][j]
其中f[i][j - 1] + f[i - 1][j] - f[i - 1][j - 1]都是以(i,j)为最右下的顶点的矩形面积(差分数组的矩形),问题是我们怎么通过控制顶点的a[i][j]来控制矩阵的大小。

屏幕截图 2024-10-12 084220.png

红色点是矩形的左上角,在此之前的所有点都为0,那么前缀和自然也为0,那么a[x1][y1] = 1,到了橘色点,矩形已经结束了,可是前缀和依然为1,因此a[x2 + 1][y1] = -1,同理另一个橘色点a[x1][y2 + 1] = -1 ,到了紫色点,由于两个橘色点,紫色点的前缀和为1,所以a[x2 + 1][y2 + 1] = 1

然后推广就可以了,利用前缀和性质,只要不是0的点就是覆盖的点,求面积即可

构造差分数组 前缀和构建矩形 再次前缀和求覆盖面积

C++ 代码#

Copy
#include <bits/stdc++.h> using namespace std; const int N = 110; int f[N][N]; int n; int main() { cin >> n; while (n -- ) { int a , b , x , y; cin >> a >> b >> x >> y; a ++ , b ++ ; f[a][b] += 1; f[x + 1][b] -= 1 , f[a][y + 1] -= 1; f[x + 1][y + 1] += 1; } for(int i = 1 ; i < N ; i ++) for(int j = 1 ; j < N ; j ++) f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1]; for(int i = 1 ; i < N ; i ++) for(int j = 1 ; j < N ; j ++){ if(f[i][j]) f[i][j] = 1; f[i][j] += f[i - 1][j] + f[i][j - 1] - f[i - 1][j - 1]; } cout << f[N - 1][N - 1]; }
posted @   她说戴了不算給  阅读(12)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示
目录