【JZOJ】幻灯片

幻灯片

第一行,一个 n n
接下来每行五个整数 x 1 , y 1 , x 2 , y 2 , k x1,y1,x2,y2,k ,代表 ( x 1 , y 1 ) (x1,y1) ( x 2 , y 2 ) (x2,y2) k k 颜色,
颜色可以重叠,但是会变成其他颜色,一个数字代表一个颜色

样例输入
3
2 2 3 3 2
2 0 4 4 1
1 1 3 5 3
样例输出
4

思路

如果用暴力的话,会TLE一半,就是只能拿50分
这是我的50分暴力

#include<iostream>
#include<cstdio>
using namespace std;
int f[25025][20025],a[1000005];
int n,minx,miny,maxx,maxy,ans;
int main()
{
	freopen("b.in","r",stdin);
	freopen("b.out","w",stdout);
	scanf("%d",&n);
	for(int k=1;k<=n;++k)
	{
		int x1,y1,x2,y2,t;
		scanf("%d%d%d%d%d",&x1,&y1,&x2,&y2,&t);
		for(int i=x1;i<=x2;++i)
			for(int j=y1;j<=y2;++j)
				f[i][j]+=t;
		minx=min(minx,x1),miny=min(miny,y1);
		maxx=max(maxx,x2),maxy=max(maxy,y2);
	}
	a[0]=1;
	for(int i=minx;i<=maxx;++i)
	{
		for(int j=miny;j<=maxy;++j)
			if(!a[f[i][j]])
			{
				a[f[i][j]]++;
				ans++;
			}
	}
	printf("%d",ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

所以直接暴力肯定是不能用的
后来听巨佬讲课,说是要离散化
然后参考巨佬的标程,终于写完了
把所有坐标压进一个数组里,然后进行排序,去重(库: a l g o r i t h m algorithm
然后找坐标,把四个角赋值,最后寻找有多少个不同的颜色

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
struct whw
{
	double x,y,r,c;
	int t;
}wh[2005];
int ind[2005][2005],h[2005];
int len,tot,ans,n;
double dou[2005];
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",&wh[i].x,&wh[i].y,&wh[i].r,&wh[i].c,&wh[i].t);
		dou[++tot]=wh[i].x-0.5;dou[++tot]=wh[i].y-0.5;
		dou[++tot]=wh[i].r+0.5;dou[++tot]=wh[i].c+0.5;
		dou[++tot]=(wh[i].x+=0.5);dou[++tot]=(wh[i].y+=0.5);
		dou[++tot]=(wh[i].r-=0.5);dou[++tot]=(wh[i].c-=0.5);//压进数组
	}
	sort(dou+1,dou+tot+1)//快拍
	len=unique(dou+1,dou+tot+1)-dou-1;//去重
	for(int i=1;i<=n;++i)
	{
		wh[i].x=lower_bound(dou+1,dou+len+1,wh[i].x)-dou;
		wh[i].y=lower_bound(dou+1,dou+len+1,wh[i].y)-dou;
		wh[i].r=lower_bound(dou+1,dou+len+1,wh[i].r)-dou;
		wh[i].c=lower_bound(dou+1,dou+len+1,wh[i].c)-dou;//寻找坐标
		ind[(int)wh[i].x][(int)wh[i].y]+=wh[i].t;
		ind[(int)wh[i].r+1][(int)wh[i].y]-=wh[i].t;
		ind[(int)wh[i].x][(int)wh[i].c+1]-=wh[i].t;
		ind[(int)wh[i].r+1][(int)wh[i].c+1]+=wh[i].t;//四个角赋值
	}
	for(int i=1;i<=len;++i)
		for(int j=1;j<=len;++j)
		{
			ind[i][j]+=ind[i][j-1]+ind[i-1][j]-ind[i-1][j-1];
			if(ind[i][j] && !h[ind[i][j]]++)ans++;//寻找不同的颜色
		}
	printf("%d",ans);
	fclose(stdin);
	fclose(stdout);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/SSL_wujiajie/article/details/86627455