https://jzoj.net/junior/#main/show/1609
数据说明:
对于50%的数据,0<=X1,Y1,X2,Y2<=10^2。
对于100%的数据,0<=X1,Y1,X2,Y2<=10^9。
此题直接暴力只能得50分,通过观察100%数据可看出,虽然坐标的范围达到10^9,但数量N ≤ 100,即x,y坐标最多200个,根据题意可看出,我们并不需要关心坐标本身的大小,而是坐标之间的相对大小关系,所以此题可以使用离散化优化数据范围,再使用暴力模拟即可。
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 100;
int n,tot1,tot2,cnt1 = 0,cnt2 = 0,res = 0;
int set[N + 100][6],_x[2 * N + 100],_y[2 * N + 100],maze[2 * N + 10][2 * N + 10],ans[N * N + 100];
// 储存x1,x2 排序、去重 离散化后的涂色地图 桶,统计颜色出现次数
/*void write1(){
for(int i = 1;i <= n;i++)
printf("%d %d %d %d %d\n",set[i][1],set[i][2],set[i][3],set[i][4],set[i][5]);
printf("\n\n\n");
}
void write2(){
for(int i = 1;i <= 2 * n;i++){
for(int j = 1;j <= 2 * n;j++)
printf("%d ",maze[i][j]);
printf("\n");
}
printf("\n\n\n");
}*/
void solve(){//暴力涂色 统计颜色总数
for(int i = 1;i <= n;i++)
for(int j = set[i][1] + 1;j <= set[i][3];j++)
for(int k = set[i][2] + 1;k <= set[i][4];k++)
maze[j][k] += set[i][5];
for(int i = 1;i <= 2 * n;i++)
for(int j = 1;j <= 2 * n;j++)
if(maze[i][j] > 0)
ans[maze[i][j]]++;
for(int i = 1;i <= 10000;i++)
if(ans[i] > 0)
res++;
}
void lsh(){//离散化 对于只关心数据间相对大小的题目 进行数据规模的缩减
sort(_x + 1,_x + cnt1 + 1);
sort(_y + 1,_y + cnt2 + 1);
tot1 = unique(_x + 1,_x + cnt1 + 1) - _x - 1;//去重
tot2 = unique(_y + 1,_y + cnt2 + 1) - _y - 1;
for(int i = 1;i <= n;i++){
set[i][1] = lower_bound(_x + 1,_x + tot1 + 1,set[i][1]) - _x;//用序号替换原数
set[i][2] = lower_bound(_y + 1,_y + tot2 + 1,set[i][2]) - _y;
set[i][3] = lower_bound(_x + 1,_x + tot1 + 1,set[i][3]) - _x;
set[i][4] = lower_bound(_y + 1,_y + tot2 + 1,set[i][4]) - _y;
}
}
int main()
{
scanf("%d",&n);
memset(ans,0,sizeof ans);
memset(maze,0,sizeof maze);
for(int i = 1;i <= n;i++){
scanf("%d%d%d%d%d",&set[i][1],&set[i][2],&set[i][3],&set[i][4],&set[i][5]);
_x[++cnt1] = set[i][1];
_x[++cnt1] = set[i][3];
_y[++cnt2] = set[i][2];
_y[++cnt2] = set[i][4];
}
lsh();
solve();
//write1();
//write2();
printf("%d",res);
return 0;
}