Codeforces Round #587 (Div. 3)C--White Sheet(矩形交,三種解法)

http://codeforces.com/contest/1216/problem/C

題意:白色矩形是否被黑色矩形完全覆蓋,是輸出NO

 

解法:

如果只說對角線沒說明是哪條對角線:

  if(a1.x1>a1.x2)swap(a1.x1,a1.x2);
  if(a1.y1>a1.y2)swap(a1.y1,a1.y2);
if(a2.x1>a2.x2)swap(a2.x1,a2.x2);
if(a2.y1>a2.y2)swap(a2.y1,a2.y2);

 

一.相交面積==白色

這做法看起來思路簡單但是很多坑

應該是兩個黑白相交面積之和-黑黑白相交面積,而不是-黑黑相交面積!(當時就wa在這)

求相交面積先判斷是否相交(即x1,x2大小與y1,y2大小)

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
struct c1{
    ll x1,y1,x2,y2;
};
c1 jiao(c1 a,c1 b){//相交矩形座標(可能不存在)
    c1 c;
    c.x1 = max(a.x1, b.x1);
    c.y1 = max(a.y1, b.y1);
    c.x2 = min(a.x2, b.x2);
    c.y2 = min(a.y2, b.y2);
    return c;
}
int main(){

    c1 a1,a2,b;
    cin>>b.x1>>b.y1>>b.x2>>b.y2>>a1.x1>>a1.y1>>a1.x2>>a1.y2>>a2.x1>>a2.y1>>a2.x2>>a2.y2;
    c1 j1=jiao(b,a1);
    c1 j2=jiao(b,a2);
    c1 j3=jiao(j1,j2);
    ll s,s1,s2,s3;
    if(b.x1>b.x2||b.y1>b.y2)s=0;//特判!
    else s=(b.x2-b.x1)*(b.y2-b.y1);
    if(j1.x1>j1.x2||j1.y1>j1.y2)s1=0;
    else s1=(j1.x2-j1.x1)*(j1.y2-j1.y1);
    if(j2.x1>j2.x2||j2.y1>j2.y2)s2=0;
    else s2=(j2.x2-j2.x1)*(j2.y2-j2.y1);
    if(j3.x1>j3.x2||j3.y1>j3.y2)s3=0;
    else s3=(j3.x2-j3.x1)*(j3.y2-j3.y1);
    if(s1+s2-s3==s)cout<<"NO"<<endl;
    else cout<<"YES"<<endl;
}

 

二.分類討論

根據黑白相對方位,上下左右分別判斷

#include<bits/stdc++.h>
using namespace std;
struct node
{
	int x1,x2,y1,y2;
}a,b,c;
int main()
{
	cin>>a.x1>>a.y1>>a.x2>>a.y2>>b.x1>>b.y1>>b.x2>>b.y2>>c.x1>>c.y1>>c.x2>>c.y2;
	if(c.x1<=a.x1&&c.x2>=a.x2 &&c.y1<=a.y1&&c.y2>=a.y2 ) puts("NO");
	else if(b.x1<=a.x1&&b.x2>=a.x2 &&b.y1<=a.y1&&b.y2>=a.y2 ) puts("NO");
	else if(c.x1<=a.x1&&c.x2>=a.x2&&b.x1<=a.x1&&b.x2>=a.x2&&b.y1<=a.y1&&c.y2>=a.y2&&b.y2>=c.y1) puts("NO");
	else if(c.x1<=a.x1&&c.x2>=a.x2&&b.x1<=a.x1&&b.x2>=a.x2&&c.y1<=a.y1&&b.y2>=a.y2&&c.y2>=b.y1) puts("NO");
    else if(c.y1<=a.y1&&c.y2>=a.y2&&b.y1<=a.y1&&b.y2>=a.y2&&b.x1<=a.x1&&c.x2>=a.x2&&b.x2>=c.x1) puts("NO");
    else if(c.y1<=a.y1&&c.y2>=a.y2&&b.y1<=a.y1&&b.y2>=a.y2&&c.x1<=a.x1&&b.x2>=a.x2&&c.x2>=b.x1) puts("NO");
    else puts("YES");
}

 

三.離散化➕二維數組vis覆蓋

注意有種情況,只覆蓋相鄰兩個整點,剩下中間不是整點所以*2,*2+-1代表附近半格

#include<bits/stdc++.h>
#define maxl 300010
using namespace std;
 
int n,m,ans,cntx,cnty,totx,toty;
int x[7],y[7];
int numx[200],numy[200];
int a[200][200];
char s[maxl];
 
inline void prework()
{
	for(int i=1;i<=6;i++)
	{
		scanf("%d%d",&x[i],&y[i]);
		x[i]*=2;y[i]*=2;
		numx[++cntx]=x[i];
		numx[++cntx]=x[i]-1;
		numx[++cntx]=x[i]+1;
		numy[++cnty]=y[i];
		numy[++cnty]=y[i]-1;
		numy[++cnty]=y[i]+1;
	}
	sort(numx+1,numx+1+cntx);
	sort(numy+1,numy+1+cnty);
	totx=unique(numx+1,numx+1+cntx)-numx-1;
	toty=unique(numy+1,numy+1+cnty)-numy-1;
}
 
inline void mainwork()
{
	int x1,x2,y1,y2;
	x1=lower_bound(numx+1,numx+1+totx,x[3])-numx;
	x2=lower_bound(numx+1,numx+1+totx,x[4])-numx;
	y1=lower_bound(numy+1,numy+1+toty,y[3])-numy;
	y2=lower_bound(numy+1,numy+1+toty,y[4])-numy;
	for(int i=x1;i<=x2;i++)
		for(int j=y1;j<=y2;j++)
			a[i][j]=1;
	x1=lower_bound(numx+1,numx+1+totx,x[5])-numx;
	x2=lower_bound(numx+1,numx+1+totx,x[6])-numx;
	y1=lower_bound(numy+1,numy+1+toty,y[5])-numy;
	y2=lower_bound(numy+1,numy+1+toty,y[6])-numy;
	for(int i=x1;i<=x2;i++)
		for(int j=y1;j<=y2;j++)
			a[i][j]=1;
	ans=0;
	x1=lower_bound(numx+1,numx+1+totx,x[1])-numx;
	x2=lower_bound(numx+1,numx+1+totx,x[2])-numx;
	y1=lower_bound(numy+1,numy+1+toty,y[1])-numy;
	y2=lower_bound(numy+1,numy+1+toty,y[2])-numy;
	for(int i=x1;i<=x2;i++)
		for(int j=y1;j<=y2;j++)
		if(a[i][j]==0)
			ans=1;
}
 
inline void print()
{
	if(ans>0)
		puts("YES");
	else
		puts("NO");
}
 
int main()
{
	int t=1;
	//scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章