版权声明:欢迎借鉴,谢绝抄搬。 https://blog.csdn.net/ssllyf/article/details/86643478
幻灯片
题目大意:
有n个幻灯片映在一起,每个幻灯片的的左上角是a1,a2,右上角是a3,a4,颜色是a5当多个幻灯片在同一个位置时,颜色就是他们的和,求有所少种颜色
样例输入
3
2 2 3 3 2
2 0 4 4 1
1 1 3 5 3
样例输出
4
数据范围限制
提示
数据说明:
对于50%的数据,0<=X1,Y1,X2,Y2<=10^2。
对于100%的数据,0<=X1,Y1,X2,Y2<=10^9。
解题思路:
这道题只能拿50分暴力,想拿100分首先要离散化(注意:这里要加0.5或减0.5,要不然会有bug),离散化要排序,去重,然后还要将去重后的位置放回原处,这样就可以省下很多空间,时间,然后用一种差分,快速推出每一个地方的颜色
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int w,n,len,ans,b[1005][1005],pd[10005];
double f[1005];
struct rec
{
double x1,x2,y1,y2;//每一个幻灯片
int c;
}a[105];
int main()
{
freopen("b.in","r",stdin);
freopen("b.out","w",stdout);
scanf("%d",&n);
for (int i=1;i<=n;i++)
{
scanf("%lf %lf %lf %lf %d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2,&a[i].c);
f[++w]=a[i].x1-0.5;//全是避免bug
f[++w]=a[i].y1-0.5;
f[++w]=a[i].x2+0.5;
f[++w]=a[i].y2+0.5;
f[++w]=(a[i].x1+=0.5);
f[++w]=(a[i].y1+=0.5);
f[++w]=(a[i].x2-=0.5);
f[++w]=(a[i].y2-=0.5);
}
sort(f+1,f+1+w);//排序
len=unique(f+1,f+1+w)-f-1;//去重
for (int i=1;i<=n;i++)
{
a[i].x1=lower_bound(f+1,f+1+len,a[i].x1)-f;//先二分查找,再放回去,离散化
a[i].y1=lower_bound(f+1,f+1+len,a[i].y1)-f;
a[i].x2=lower_bound(f+1,f+1+len,a[i].x2)-f;
a[i].y2=lower_bound(f+1,f+1+len,a[i].y2)-f;
b[(int)a[i].x1][(int)a[i].y1]+=a[i].c;//左上角
b[(int)a[i].x2+1][(int)a[i].y2+1]+=a[i].c;//右下角
b[(int)a[i].x1][(int)a[i].y2+1]-=a[i].c;//右上角
b[(int)a[i].x2+1][(int)a[i].y1]-=a[i].c;//左下角
}
for (int i=1;i<=len;i++)
for (int j=1;j<=len;j++)
{
b[i][j]+=b[i-1][j]+b[i][j-1]-b[i-1][j-1];//差分
if ((b[i][j])&&(!pd[b[i][j]]))//判断是否记录过和是否有颜色
ans++,pd[b[i][j]]++;//颜色种数加一
}
printf("%d",ans);//输出
fclose(stdin);
fclose(stdout);
return 0;
}