题目难度:普及一
题目传送门
地毯
题目描述
在 n × n n\times n n×n 的格子上有 m m m 个地毯。
给出这些地毯的信息,问每个点被多少个地毯覆盖。
输入格式
第一行,两个正整数 n , m n,m n,m。意义如题所述。
接下来 m m m 行,每行两个坐标 ( x 1 , y 1 ) (x_1,y_1) (x1,y1) 和 ( x 2 , y 2 ) (x_2,y_2) (x2,y2),代表一块地毯,左上角是 ( x 1 , y 1 ) (x_1,y_1) (x1,y1),右下角是 ( x 2 , y 2 ) (x_2,y_2) (x2,y2)。
输出格式
输出 n n n 行,每行 n n n 个正整数。
第 i i i 行第 j j j 列的正整数表示 ( i , j ) (i,j) (i,j) 这个格子被多少个地毯覆盖。
样例 #1
样例输入 #1
5 3
2 2 3 3
3 3 5 5
1 2 1 4
样例输出 #1
0 1 1 1 0
0 1 1 0 0
0 1 2 1 1
0 0 1 1 1
0 0 1 1 1
提示
样例解释
覆盖第一个地毯后:
0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 |
---|---|---|---|---|
0 0 0 | 1 1 1 | 1 1 1 | 0 0 0 | 0 0 0 |
0 0 0 | 1 1 1 | 1 1 1 | 0 0 0 | 0 0 0 |
0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 |
0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 |
覆盖第一、二个地毯后:
0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 | 0 0 0 |
---|---|---|---|---|
0 0 0 | 1 1 1 | 1 1 1 | 0 0 0 | 0 0 0 |
0 0 0 | 1 1 1 | 2 2 2 | 1 1 1 | 1 1 1 |
0 0 0 | 0 0 0 | 1 1 1 | 1 1 1 | 1 1 1 |
0 0 0 | 0 0 0 | 1 1 1 | 1 1 1 | 1 1 1 |
覆盖所有地毯后:
0 0 0 | 1 1 1 | 1 1 1 | 1 1 1 | 0 0 0 |
---|---|---|---|---|
0 0 0 | 1 1 1 | 1 1 1 | 0 0 0 | 0 0 0 |
0 0 0 | 1 1 1 | 2 2 2 | 1 1 1 | 1 1 1 |
0 0 0 | 0 0 0 | 1 1 1 | 1 1 1 | 1 1 1 |
0 0 0 | 0 0 0 | 1 1 1 | 1 1 1 | 1 1 1 |
数据范围
对于 20 % 20\% 20% 的数据,有 n ≤ 50 n\le 50 n≤50, m ≤ 100 m\le 100 m≤100。
对于 100 % 100\% 100% 的数据,有 n , m ≤ 1000 n,m\le 1000 n,m≤1000。
题目分析:这题数据太水,打暴力都能AC,时间复杂度为O(m*n^2)可以过。
暴力代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1100;int a[N][N];
int n,m;ll read()
{ll s=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}return s*f;
}int main() {n = read(),m = read();for(int i = 1; i <= m; i++){int x1 = read(), y1 = read(),x2 = read(),y2 = read();for(int x = x1; x <= x2; x++){for(int y = y1; y <= y2; y++) a[x][y]++;}}for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++) cout<<a[i][j]<<' ';cout<<'\n';} return 0;
}
*下面介绍下法二:**二维差分***
代码部分:```cpp#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1100;int a[N][N],b[N][N];
int n,m;void insert(int x1,int y1,int x2,int y2,int c)
{b[x1][y1] += c;b[x1][y2 + 1] -= c;b[x2 + 1][y1] -= c;b[x2 + 1][y2 + 1] += c;
}ll read()
{ll s=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}return s*f;
}int main() {n = read(),m = read();for(int i = 1; i <= m; i++){int x1 = read(), y1 = read(),x2 = read(),y2 = read();insert(x1,y1,x2,y2,1);}for(int i = 1; i <= n; i++){for(int j = 1; j <= n; j++) {b[i][j] += b[i - 1][j] + b[i][j - 1]-b[i - 1][j - 1];cout<<b[i][j]<<' '; }cout<<'\n';} return 0;
}