幻灯片

博客围绕纪中jzoj 1609题目展开,题目是n个幻灯片映在一起,求不同位置颜色和的种类数。数据范围跨度大,解题思路是先处理幻灯片粘着不重合的特殊情况,再进行离散化(排序、去重并放回原位),最后用差分推出颜色并统计个数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

幻 灯 片 幻灯片

题目链接:jzoj 1609

题目大意

有n个幻灯片映在一起,每个幻灯片的的左上角是a1,a2,右上角是a3,a4,颜色是a5当多个幻灯片在同一个位置时,那个位置的颜色就是他们的和,求有多少种颜色。

样例输入

3
2 2 3 3 2
2 0 4 4 1
1 1 3 5 3

样例输出

4

数据范围

对于 50 % 50% 50的数据, 0 &lt; = X 1 , Y 1 , X 2 , Y 2 &lt; = 1 0 2 0&lt;=X1,Y1,X2,Y2&lt;=10^2 0<=X1,Y1,X2,Y2<=102
对于 100 % 100% 100的数据, 0 &lt; = X 1 , Y 1 , X 2 , Y 2 &lt; = 1 0 9 ; 1 &lt; = N &lt; = 100 0&lt;=X1,Y1,X2,Y2&lt;=10^9;1&lt;=N&lt;=100 0<=X1,Y1,X2,Y2<=1091<=N<=100

思路

这道题要用到离散化和差分。
不过一开始,为了处理两个幻灯片粘着却不重合的特殊情况,我们要做一些处理(幻灯片的边加 0.5 0.5 0.5或减 0.5 0.5 0.5)。
接着,我们要离散化。离散化之前,要排序和去重,还要把去重后的坐标放回原位。
然后,我们可以用差分,推出每一个地方的颜色。我们在推的过程中,可以统计出颜色的个数了。

代码

#include<cstdio>
#include<algorithm>
using namespace std;
struct note
{
	int x1,y1,x2,y2,c;
}a[101];
int n,b[801],k,l,f[1001][1001],ans;
bool in[10001];
int main()
{
//	freopen("b.in","r",stdin);
//	freopen("b.out","w",stdout);
	scanf("%d",&n);//读入
	for (int i=1;i<=n;i++)
	{
		scanf("%d%d%d%d%d",&a[i].x1,&a[i].y1,&a[i].x2,&a[i].y2,&a[i].c);//读入
		b[++k]=a[i].x1-0.5;//去除粘着却不重合的情况
		b[++k]=a[i].y1-0.5;
		b[++k]=a[i].x2+0.5;
		b[++k]=a[i].y2+0.5;
		b[++k]=a[i].x1+=0.5;
		b[++k]=a[i].y1+=0.5;
		b[++k]=a[i].x2-=0.5;
		b[++k]=a[i].y2-=0.5;
	}
	sort(b+1,b+k+1);//排序
	l=unique(b+1,b+k+1)-b-1;//去重
	for (int i=1;i<=n;i++)
	{
		a[i].x1=lower_bound(b+1,b+l+1,a[i].x1)-b;//离散化
		a[i].y1=lower_bound(b+1,b+l+1,a[i].y1)-b;
		a[i].x2=lower_bound(b+1,b+l+1,a[i].x2)-b;
		a[i].y2=lower_bound(b+1,b+l+1,a[i].y2)-b;
		//四个角
		f[a[i].x1][a[i].y1]+=a[i].c;//左上角
		f[a[i].x2+1][a[i].y2+1]+=a[i].c;//右下角
		f[a[i].x1][a[i].y2+1]-=a[i].c;//右上角
		f[a[i].x2+1][a[i].y1]-=a[i].c;//左下角
	}
	for (int i=1;i<=l;i++)
	for (int j=1;j<=l;j++)
	{
		f[i][j]+=f[i-1][j]+f[i][j-1]-f[i-1][j-1];//差分
		if (f[i][j]&&!in[f[i][j]])//如果有颜色且颜色没标记过
		{
			in[f[i][j]]=1;//标记
			ans++;//颜色数加一
		}
	}
	printf("%d",ans);//输出颜色数
//	fclose(stdin);
//	fclose(stdout);
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值