【离散化】【差分】幻灯片(jzoj 1609)

版权声明:欢迎借鉴,谢绝抄搬。 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;
} 

猜你喜欢

转载自blog.csdn.net/ssllyf/article/details/86643478