P4557 [JSOI2018]战争
首先可以题目描述的两个点集是两个凸包,分别设为A和B。
考虑一个向量w不合法的条件。
即存在b+w=a,其中a属于A,b属于B。
也就是a-b=w。
即对b取反后和a的闵可夫斯基和。
求出闵可夫斯基和后check点是否在凸包内即可,在凸包内说明不合法。
#include<iostream>
#include<cctype>
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<ctime>
#include<cstdlib>
#include<algorithm>
#define N 330000
#define L 300000
#define eps 1e-15
#define inf 1e18+7
#define db double
#define ll long long
#define ldb long double
using namespace std;
inline int read()
{
char ch=0;
int x=0,flag=1;
while(!isdigit(ch)){ch=getchar();if(ch=='-')flag=-1;}
while(isdigit(ch)){x=(x<<3)+(x<<1)+ch-'0';ch=getchar();}
return x*flag;
}
int dcmp(db x){if(fabs(x)<=eps)return 0;else return (x>0)?+1:-1;}
struct vec
{
db x,y;
vec operator+(vec a){return (vec){x+a.x,y+a.y};}
vec operator-(vec a){return (vec){x-a.x,y-a.y};}
db ang(){return atan2(y,x);}
};
typedef vec pot;
db cross(vec a,vec b){return a.x*b.y-b.x*a.y;}
bool cmp_vec(vec a,vec b){return a.ang()<b.ang();}
bool cmp_pot(pot a,pot b){if(dcmp(a.x-b.x))return a.x<b.x;else return a.y<b.y;}
vec f[N];
pot a[N],b[N],p[N],t[N],v[N],s[N];
int main()
{
int n=read(),m=read(),qnum=read(),top,num,num_,cnt=0,tot=0;
pot P={-inf,-inf},Q={-inf,-inf};
for(int i=1;i<=n;i++)a[i].x=+read(),a[i].y=+read();
num=0;sort(a+1,a+n+1,cmp_pot);top=0;
for(int i=1;i<=n;i++)
{
while(top>1&&dcmp(cross(s[top]-s[top-1],a[i]-s[top-1]))!=+1)top--;
s[++top]=a[i];
}
for(int i=1;i<=top;i++)t[++num]=s[i];top=0;
for(int i=1;i<=n;i++)
{
while(top>1&&dcmp(cross(s[top]-s[top-1],a[i]-s[top-1]))!=-1)top--;
s[++top]=a[i];
}
for(int i=top;i>=1;i--)t[++num]=s[i];num_=0;
for(int i=1;i<=num;i++)
{
if(i==num&&!dcmp(t[i].x-t[1].x)&&!dcmp(t[i].y-t[1].y))continue;
if(i!=1&&!dcmp(t[i].x-t[i-1].x)&&!dcmp(t[i].y-t[i-1].y))continue;
v[++num_]=t[i];
}
for(int i=1;i<=num_;i++)
{
if(dcmp(v[i].y-P.y)==0&&dcmp(v[i].x-P.x)<0)P=v[i];
if(dcmp(v[i].y-P.y)>0)P=v[i];
if(i!=1)f[++cnt]=v[i]-v[i-1];if(i==num_)f[++cnt]=v[1]-v[i];
}
for(int i=1;i<=m;i++)b[i].x=-read(),b[i].y=-read();
num=0;sort(b+1,b+m+1,cmp_pot);top=0;
for(int i=1;i<=m;i++)
{
while(top>1&&dcmp(cross(s[top]-s[top-1],b[i]-s[top-1]))!=+1)top--;
s[++top]=b[i];
}
for(int i=1;i<=top;i++)t[++num]=s[i];top=0;
for(int i=1;i<=m;i++)
{
while(top>1&&dcmp(cross(s[top]-s[top-1],b[i]-s[top-1]))!=-1)top--;
s[++top]=b[i];
}
for(int i=top;i>=1;i--)t[++num]=s[i];num_=0;
for(int i=1;i<=num;i++)
{
if(i==num&&!dcmp(t[i].x-t[1].x)&&!dcmp(t[i].y-t[1].y))continue;
if(i!=1&&!dcmp(t[i].x-t[i-1].x)&&!dcmp(t[i].y-t[i-1].y))continue;
v[++num_]=t[i];
}
for(int i=1;i<=num_;i++)
{
if(dcmp(v[i].y-Q.y)==0&&dcmp(v[i].x-Q.x)<0)Q=v[i];
if(dcmp(v[i].y-Q.y)>0)Q=v[i];
if(i!=1)f[++cnt]=v[i]-v[i-1];if(i==num_)f[++cnt]=v[1]-v[i];
}
sort(f+1,f+cnt+1,cmp_vec);
pot k=P+Q;p[++tot]=k;
for(int i=1;i<=cnt;i++)
{
k=k+f[i];
if(i!=cnt&&dcmp(f[i].x*f[i+1].y-f[i].y*f[i+1].x)==0)continue;
p[++tot]=k;
}
tot--;k=p[1];
for(int i=1;i<=qnum;i++)
{
pot o;
o.x=read();o.y=read();
if(dcmp(cross(p[2]-k,o-k))==-1||dcmp(cross(p[tot]-k,o-k))==+1){printf("0\n");continue;}
int l=2,r=tot-1,mid;
while(l<r)
{
mid=((l+r)>>1)+1;
if(dcmp(cross(p[mid]-k,o-k))==+1)l=mid;
else r=mid-1;
}
if(dcmp(cross(p[l+1]-p[l],o-p[l]))!=-1)printf("1\n");else printf("0\n");
}
return 0;
}
P4557 [JSOI2018]战争的更多相关文章
- 洛谷P4557 [JSOI2018]战争(闵可夫斯基和+凸包)
题面 传送门 题解 看出这是个闵可夫斯基和了然而我当初因为见到这词汇是在\(shadowice\)巨巨的\(Ynoi\)题解里所以压根没敢学-- 首先您需要知道这个 首先如果有一个向量\(w\)使得\ ...
- [JSOI2018]战争
题目描述 九条可怜是一个热爱读书的女孩子. 在她最近正在读的一本小说中,描述了两个敌对部落之间的故事.第一个部落有 nnn 个人,第二个部落有 mmm 个人,每一个人的位置可以抽象成二维平面上坐标为 ...
- BZOJ5317:[JSOI2018]战争(闵可夫斯基和)
令 \(a\in A,b\in B\) 则移动向量 \(\omega\) 使得存在 \(b+\omega=a\) 那么 \(\omega\) 需要满足 \(\omega=a−b\) 黑科技:闵可夫斯基 ...
- [JSOI2018]战争(闵可夫斯基和)
害怕,可怜几何题 果然不会 题目就是说给你两个凸包,每次询问给你一个向量 \(c\) 问你能不能从两个凸包 \(A\) , \(B\) 里分别找到一个点 \(a\) , \(b\) 满足 \(a+c= ...
- 【LuoguP4557】[JSOI2018]战争
题目链接 题意 给你两个点集. q次询问 , 每次把其中一个点集往一个方向移动 , 问两个点集的凸包还有没有交. Sol 闵可夫斯基和板子题. 把问题做如下转换: 我们本来两个凸包相交是相当于是对于移 ...
- 计算几何细节梳理&模板
点击%XZY巨佬 向量的板子 #include<bits/stdc++.h> #define I inline using namespace std; typedef double DB ...
- HHHOJ #151. 「NOI模拟 #2」Nagisa
计算几何板子题(我才没有拷板子的说--) 众所周知,三角形的重心坐标是\((\frac{x_1+x_2+x_3}{3},\frac{y_1+y_2+y_3}{3})\) 然后我们发现如果我们有一个点集 ...
- 【学习笔记】Minkowski和
这还是个被我咕了N久的玩意 Minkowski和是一个奇怪的玩意 他长这样 $S={a+b \| a \in A , b \in B}$ AB可以是点集也可是向量集(显然) 他可以处理一些奇怪的东西 ...
- JSOI部分题解
JSOI部分题解 JSOI2018 战争 问题转化为给定你两个凸包\(\mathbb S,\mathbb T\),每次独立的询问将\(\mathbb T\)中的每个点移动一个向量,问\(\mathbb ...
随机推荐
- loj#2510. 「AHOI / HNOI2018」道路 记忆化,dp
题目链接 https://loj.ac/problem/2510 思路 f[i][a][b]表示到i时,公路个数a,铁路个数b 记忆化 复杂度=状态数=\(nlog^2n\) 代码 #include ...
- NodeJs中npm使用
什么是 NPM npm 之于 Node ,就像 pip 之于 Python , gem 之于 Ruby , pear 之于 PHP . npm 是 Node 官方提供的包管理工具,他已经成了 Node ...
- 倍数|计蒜客2019蓝桥杯省赛 B 组模拟赛(一)
思路:从l枚举到r肯定超时,这时我们要转变思路!题目让我们求一个区间内的d的倍数,只需要求出r/d - l/d就是区间内d倍数的个数. 代码: #include <iostream> us ...
- C# 各种控件实现可拖动和调整大小
http://www.360doc.com/content/18/0516/12/55659281_754382494.shtml using System; using System.Collect ...
- (转)Paper list of Meta Learning/ Learning to Learn/ One Shot Learning/ Lifelong Learning
Meta Learning/ Learning to Learn/ One Shot Learning/ Lifelong Learning 2018-08-03 19:16:56 本文转自:http ...
- 深度学习课程笔记(三)Backpropagation 反向传播算法
深度学习课程笔记(三)Backpropagation 反向传播算法 2017.10.06 材料来自:http://speech.ee.ntu.edu.tw/~tlkagk/courses_MLDS1 ...
- Docker之Swarm
Docker学习笔记 — Swarm搭建Docker集群 Swarm在schedule节点运行容器的时候,会根据指定的策略来计算最适合运行容器的节点,目前支持的策略有:spread, binpack, ...
- java.lang.NoClassDefFoundError: com/gexin/rp/sdk/exceptions/RequestException解决方法
本文为博主原创,未经允许不得转载: 最近在开发个推的时候遇到的问题,当我在maven仓库中下载个推的jar包时,下载不下来,索性在项目中Configue build Path,将jar下载到本地 手动 ...
- mybatis结合mysql批量操作及查询sql
MySQL数据库 批量操作主要使用的是Mybatis的foreach,遍历参数列表执行相应的操作,所以批量插入/更新/删除的写法是类似的,只是SQL略有区别而已.MySql批量操作需要数据库连接配置a ...
- java 注解的使用
@Target({ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface Without ...