程序设计天梯赛——迎风一刀斩

原创 2016年05月30日 16:17:49

题目链接https://www.patest.cn/contests/gplt/L3-006

首先 设两个多边形为A和B 

由于存在翻面操作 所以可以改为分别判断A与B 和A与(B的翻面)

同理可以对B进行旋转操作,将B分成8个B' 分别和A进行比对

翻面操作(对y轴)为x=-x  旋转90度(对原点)为 x=-y y=x;

现在问题转换为判断A和B是否可以经过平移可以拼成矩形 

因为A,B拼接肯定存在公共点 所以不妨各枚举A,B上的一点Ai,Bj

将Ai,Bj平移到原点上(A,B跟着平移),然后将A、B重合的边删掉。

最后求出剩余边的上下左右4个边界 那么剩下的边必须满足处于边界上 且共计有4个点位于4角上

(因为存在顺逆时针问题,A,B都加了双向边,所以代码中判断的数目都为双倍)

并且由于切的一刀笔直的 所以之前删掉边的数目必须为2  (如果取消这个条件 即可解决切线为折线的问题)

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<vector>
#include<list>
#include<set>
#include<map>
#include<stack>
#include<queue>
#include<deque>
#define mem(x,y) memset(x,y,sizeof(x))
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
#define mp make_pair
#define bug puts("===========");
#define zjc puts("");
const double pi=(acos(-1.0));
const double eps=1e-2;
const ll INF=1e18+10;
const ll inf=1e18+10;
const int maxn=10000+50;
const int NV=10000+50;
const int NE=1e4+100;
const int MOD=1e9+7;
/*=========================*/
struct point{
    ll x,y;
    //2个向量的叉积
    friend ll det(const point &a, const point &b){ return a.x * b.y - a.y * b.x; }
    int in()  { return ~scanf("%lld %lld", &x, &y); }
    void out(){ printf("%lld %lld\n", x, y); }
    bool operator < (const point &b) const{
        return x<b.x||(x==b.x&&y<b.y);
    }
    bool operator == (const point &b) const{
        return x==b.x&&y==b.y;
    }
};
struct line{
     point s,t;
    line(const point &s = point(), const point &t = point()): s(s), t(t) {}
    bool operator < (const line &b) const{
        return s<b.s||(s==b.s&&t<b.t);
    }
    bool operator == (const line &b) const{
        return s==b.s&&t==b.t;
    }
    bool operator != (const line &b) const {
        return !(*this==b);
    }

};
struct polygon{
    #define next(i) ((i+1)%n)
    int n;
    vector<point> p;
    polygon(int n=0): n(n){ p.resize(n); }
   void in() {
        scanf("%d",&n);
         p.clear(); point pp;
         for(int i=0;i<n;i++){
                pp.in();
                p.push_back(pp);
        }
    }
    void fan(){
        for(int i=0;i<n;i++) {
            p[i].x=-p[i].x;
        }
    }
    void ro(){
        for(int i=0;i<n;i++) {
            ll xxx=p[i].x;
            p[i].x=-p[i].y;
            p[i].y=xxx;
        }
    }
    void go(int id){
        int xx=p[id].x,yy=p[id].y;
        for(int i=0;i<n;i++) {
            p[i].x-=xx;
            p[i].y-=yy;
        }
    }
}p1,p2;
vector<line>vec,ans;
vector<point> pp;
bool check(int a,int b,polygon p1,polygon p2){
    p1.go(a); p2.go(b);
    vec.clear(); ans.clear();
    for(int i=0;i<p1.n;i++){
        vec.pb(line(p1.p[i],p1.p[(i+1)%p1.n]));
        vec.pb(line(p1.p[(i+1)%p1.n],p1.p[i]));
    }
    for(int i=0;i<p2.n;i++){
        vec.pb(line(p2.p[i],p2.p[(i+1)%p2.n]));
        vec.pb(line(p2.p[(i+1)%p2.n],p2.p[i]));
    }
    ll maxx=0,maxy=0,minx=inf,miny=inf;
    sort(vec.begin(),vec.end());
    for(int i=0;i<vec.size();i++){
        if((i==0||vec[i]!=vec[i-1])&&(i==vec.size()-1||vec[i]!=vec[i+1])){
            ans.pb(vec[i]);
            maxx=max(maxx,vec[i].s.x);
            maxx=max(maxx,vec[i].t.x);
            minx=min(minx,vec[i].s.x);
            minx=min(minx,vec[i].t.x);
            maxy=max(maxy,vec[i].s.y);
            maxy=max(maxy,vec[i].t.y);
            miny=min(miny,vec[i].s.y);
            miny=min(miny,vec[i].t.y);
        }
    }
    int cnt=0;
    for(int i=0;i<ans.size();i++){
        int flag=0;
        if(ans[i].s.x==maxx||ans[i].s.x==minx) flag++;
        if(ans[i].s.y==maxy||ans[i].s.y==miny) flag++;
        if(flag==0) return 0;
        else if(flag==2) cnt++;
        flag=0;
        if(ans[i].t.x==maxx||ans[i].t.x==minx) flag++;
        if(ans[i].t.y==maxy||ans[i].t.y==miny) flag++;
        if(flag==0) return 0;
        else if(flag==2) cnt++;
        if(ans[i].s.x!=ans[i].t.x&&ans[i].s.y!=ans[i].t.y) return 0;
    }
    return (vec.size()-ans.size()==4)&&cnt>=16;
}
bool solve(){
    for(int i=0;i<p1.n;i++)
        for(int j=0;j<p2.n;j++)
            if(check(i,j,p1,p2)) return 1;
    return 0;
}
bool go(){
    if(solve()) return 1;
    p2.ro();if(solve()) return 1;
    p2.ro();if(solve()) return 1;
    p2.ro();if(solve()) return 1;
    p2.ro();
    return 0;
}
int main()
{
    int T_T;
    scanf("%d",&T_T);
    while(T_T--){
        p1.in(); p2.in();
        if(go()) puts("YES");
        else if(p2.fan(),go()) puts("YES");
        else puts("NO");
    }
    return 0;
}



版权声明:本文为博主原创文章,未经博主允许不得转载。

AlphaGo 超快棋遍虐人类高手(职业棋手讲解及大量网友评论)

转载:AlphaGo 超快棋遍虐人类高手(职业棋手讲解及大量网友评论) 文章目录 ★Master 的60局 ★对 Master 身份的猜测 ★职业围棋高手对 AI 棋力的点评 ★...
  • zrc199021
  • zrc199021
  • 2017年01月09日 00:01
  • 4065

PAT 团体程序设计天梯赛 部分题目题解

L1-002 打印沙漏 L1-006 连续因子 L1-010 比较大小 L1-014 简单题 L1-018 大笨钟 L2-002 链表去重 L2-010 排座位 L3-002 堆栈 L3-006 迎风...
  • nike0good
  • nike0good
  • 2016年07月12日 11:18
  • 2608

一个简单的剪刀石头布游戏(C++实现)

首先先看下面这个C++实现,它实现了剪刀石头布的游戏,并且在退出游戏时会打印游戏结果。其设计思路是将rock,paper和scissors分别初始化为0,1,2后(由C++11的强类型枚举enum实现...
  • Demorngel
  • Demorngel
  • 2017年04月21日 21:45
  • 2547

天梯赛练习集 L3-006 迎风一刀斩

迎风一刀斩看到这题的时候一脸懵逼。。。后来才发现原来旋转角度只有90度、180度、或270度。。。不过还是查了一下题解。。。其实只有四种情况,只要会画就差不多会写了。解释一下代码。。。 check(...
  • woshirenNo01
  • woshirenNo01
  • 2017年03月14日 19:38
  • 621

团体程序设计天梯赛L3-008——喊山(bfs)

喊山,是人双手围在嘴边成喇叭状,对着远方高山发出“喂—喂喂—喂喂喂……”的呼唤。呼唤声通过空气的传递,回荡于深谷之间,传送到人们耳中,发出约定俗成的“讯号”,达到声讯传递交流的目的。原来它是彝族先民用...
  • blue_skyrim
  • blue_skyrim
  • 2016年07月15日 15:12
  • 800

团体程序设计天梯赛——排座位(dfs)

布置宴席最微妙的事情,就是给前来参宴的各位宾客安排座位。无论如何,总不能把两个死对头排到同一张宴会桌旁!这个艰巨任务现在就交给你,对任何一对客人,请编写程序告诉主人他们是否能被安排同席。输入格式:输入...
  • blue_skyrim
  • blue_skyrim
  • 2017年03月20日 21:02
  • 652

团体程序设计天梯赛——红色警报(dfs)

战争中保持各个城市间的连通性非常重要。本题要求你编写一个报警程序,当失去一个城市导致国家被分裂为多个无法连通的区域时,就发出红色警报。注意:若该国本来就不完全连通,是分裂的k个区域,而失去一个城市并不...
  • blue_skyrim
  • blue_skyrim
  • 2017年03月22日 20:09
  • 391

团体程序设计天梯赛——玩转二叉树(遍历构造二叉树)

给定一棵二叉树的中序遍历和前序遍历,请你先将树做个镜面反转,再输出反转后的层序遍历的序列。所谓镜面反转,是指将所有非叶结点的左右孩子对换。这里假设键值都是互不相等的正整数。输入格式:输入第一行给出一个...
  • blue_skyrim
  • blue_skyrim
  • 2017年03月21日 16:34
  • 479

一刀斩绿色免安装杀毒软件

  • 2009年11月20日 17:11
  • 378KB
  • 下载

流行病毒专杀工具 一刀斩 V2006.6.28绿色特别版

  • 2006年07月05日 16:16
  • 0B
  • 下载
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:程序设计天梯赛——迎风一刀斩
举报原因:
原因补充:

(最多只允许输入30个字)