codeforces 993 A

codeforces 993 A

A. Two Squares

introduction

判断两个正方形是否相交(只有一个有公共点也算相交),其中一个平放,另一个倾斜45°。

method

方法有很多,从直观上都可以理解。但我的方法太麻烦了,失败了。
觉得题解的思路很好,所以记录一下。
为了便于描述,平放的正方形记为A,倾斜45°的记为B
相交可以分为4种情况:

  1. B的角落在A
  2. A的角落在B
  3. B的中心落在A
  4. A的中心落在B

第一种情况好判断,按照是两个平放的正方形来处理。难点是AB中的情况。
一个想法是将A旋转45°,B也旋转45°,这样就转化成第一种情况。但是这样做的代价是引入了浮点数。题解的巧妙之处就是观察到了放缩是不会改变相交性的。

replace each 𝑥 coordinate with 𝑥+𝑦 and each 𝑦 coordinate with 𝑥−𝑦

这样就完全转化成第一种情况

其他的思路
点都是整点,并且每个正方形最多是100×100,可以枚举两个正方形是否有公共点

tips

  1. 放缩是不会改变相交性的
  2. 两个平放正方形的相交性

reference

http://codeforces.com/blog/entry/60047
坐标旋转变换公式的推导
https://zh.wikipedia.org/wiki/旋转

code

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<string>
#include<vector>
#include<cmath>
#include<map>
#include<istream>
#define DEBUG(x) cout<<#x<<" = "<<x<<endl
using namespace std;
struct square{
    int x[4],y[4];
    int mxx,mix,mxy,miy;
    friend istream & operator>>(istream &in,square &s)
    {
        for(int i=0;i<4 ;i++ ){
            in>>s.x[i]>>s.y[i];
            if(i==0)s.mxx=s.mix=s.x[i],s.mxy=s.miy=s.y[i];
            else {
                s.mxx=max(s.mxx,s.x[i]);
                s.mix=min(s.mix,s.x[i]);
                s.mxy=max(s.mxy,s.y[i]);
                s.miy=min(s.miy,s.y[i]);
            }
        }
        return in;
    }
    friend ostream & operator<<(ostream &out,square &s)
    {
        for(int i=0;i<4 ;i++ ){
            out<<s.x[i]<<" "<<s.y[i]<<" ";
        }
    }
};
square roughrotate(square s)
{
    square rt;
    for(int i=0;i<4  ;i++ ){
        rt.x[i]=s.x[i]+s.y[i];
        rt.y[i]=s.x[i]-s.y[i];
        if(i==0)rt.mxx=rt.mix=rt.x[i],rt.mxy=rt.miy=rt.y[i];
        else {
                rt.mxx=max(rt.mxx,rt.x[i]);
                rt.mix=min(rt.mix,rt.x[i]);
                rt.mxy=max(rt.mxy,rt.y[i]);
                rt.miy=min(rt.miy,rt.y[i]);
        }
    }
    return rt;
}
bool isin(square p,square d)
{
    for(int i=0;i<4 ;i++ ){
        if(d.x[i]>=p.mix&&d.x[i]<=p.mxx
           &&d.y[i]>=p.miy&&d.y[i]<=p.mxy)return true;
    }
    int mdx=(d.mix+d.mxx)/2,
    mdy=(d.miy+d.mxy)/2;
    if(mdx>=p.mix&&mdx<=p.mxx&&mdy>=p.miy&&mdy<=p.mxy)return true;
    return false;
}
int main()
{
//    freopen("in.txt","r",stdin);
    square par,deg;
    cin>>par>>deg;
    bool b1=isin(par,deg);
    square par1=roughrotate(deg);
    square deg1=roughrotate(par);
    bool b2=isin(par1,deg1);
    if(b1||b2)cout<<"YES"<<endl;
    else cout<<"NO"<<endl;
}

posted @ 2018-12-30 21:39  MalcolmMeng  阅读(178)  评论(0编辑  收藏  举报