(纪中)2367. 【2019.11NOIP普及组模拟】白板【离散化】

(File IO): input:sheet.in output:sheet.out
时间限制: 1000 ms 空间限制: 528400 KB 具体限制


题目描述
在这里插入图片描述


输入
在这里插入图片描述

输出
在这里插入图片描述


样例输入
3
2 2 4 4
1 1 3 5
3 1 5 5
3 3 7 5
0 0 4 6
0 0 7 4
5 2 10 5
3 1 7 6
8 1 11 7

样例输出
NO
YES
YES

第一个例子中,白板被黑板完全覆盖。
第二个例子中,部分白板可以看到。比如(6.5,4.5)这个点就可以被看到。


数据范围限制
在这里插入图片描述


解题思路
当时做这道题时,调了好久,55分,最后发现,被题目误导了。
题目说 “ 第二个例子中,部分白板可以看到。比如(6.5,4.5)这个点就可以被看到。 ”其实画图可得,是(7,4)。。。而且根据样例发现,其实是看到白板中的一个格,并不是一个点,代表白板未被覆盖。
这道题可以用离散化算法。。。
离散化处理
把三个板的x坐标和y坐标分别存入x和y数组,从小到大排序,再把坐标替换成坐标的排序结果,就是这个坐标的大小排位,这个排位和平常的考试排位一样。比如:1 2 5 5 7 的名次排序是 1 2 3 3 5。


代码
100分

#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
long long f[10][10],k,ans,n,a[1000][1000];
struct c{
	int x,y,s;
}x[100],y[100];
bool cmp(const c&l,const c&r){
	return l.x<r.x;
}
int read()
{
	for(int i=1;i<=3;i++){
		scanf("%lld%lld%lld%lld",&f[i][1],&f[i][2],&f[i][3],&f[i][4]);
		x[i].x=f[i][1],x[i].y=1,x[i].s=i;//.x存坐标数,用来排序;.y存这个坐标是左下x还是左下y、右上x、右上y
		x[i+3].x=f[i][3],x[i+3].y=3,x[i+3].s=i;//+3是因为要存6个,左下x存前三个,右上的x存后三个
		y[i].x=f[i][2],y[i].y=2,y[i].s=i;//
		y[i+3].x=f[i][4],y[i+3].y=4,y[i+3].s=i;//同上
	}
}
void eee(){
	x[0].x=y[0].x=-1;
	for(int i=1;i<=6;i++)
	{
		if(x[i].x==x[i-1].x)f[x[i].s][x[i].y]=f[x[i-1].s][x[i-1].y];//如果和前一个点一样,就像分数和前一个人一样,就和前一个人的名次相同
		else f[x[i].s][x[i].y]=i;//如果不一样,就和i相等
		if(y[i].x==y[i-1].x)f[y[i].s][y[i].y]=f[y[i-1].s][y[i-1].y];
		else f[y[i].s][y[i].y]=i;
	}
}
void hhh(){
	for(int i=f[1][1]+1;i<=f[1][3];i++)//范围:这里因为提目需求面,但是给的是点,可以-1(简单粗暴)
		for(int j=f[1][2]+1;j<=f[1][4];j++)
			a[i][j]=1;//标记白板
    for(int i=f[2][1]+1;i<=f[2][3];i++)
		for(int j=f[2][2]+1;j<=f[2][4];j++)
			a[i][j]=0;//标记黑板
    for(int i=f[3][1]+1;i<=f[3][3];i++)
		for(int j=f[3][2]+1;j<=f[3][4];j++)
			a[i][j]=0;//标记黑板
	for(int i=f[1][1]+1;i<=f[1][3];i++){
		for(int j=f[1][2]+1;j<=f[1][4];j++)
			if(a[i][j])//查找白板标记
			{
				ans=1;
				return;
			}
    }
}
int main()
{	
    freopen("sheet.in","r",stdin); 
	freopen("sheet.out","w",stdout);
    scanf("%lld",&n);
	for(long long i=1; i<=n; i++)
	{	
	    ans=0;
		read();//读入,顺便预处理把坐标存起来
		sort(x+1,x+6+1,cmp);//
		sort(y+1,y+6+1,cmp);//从小到大排序(我也不知道我为什么要写两个cmp)
		eee();//把坐标替换
		hhh();//50分的统计
		if(ans)
			cout<<"YES"<<endl;
		else
			cout<<"NO"<<endl;
	}
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值