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 ...
随机推荐
- linux--磁盘及文件系统管理
磁盘管理 : 主流的磁盘 : 机械式硬盘 常见的有 : U盘, 光盘, 软盘, 硬盘, 磁带机 扇区 : sector 磁道 : track 柱面 : cylinder 磁盘出厂时 : 低级格式化 : ...
- dll注入到指定进程
talk is cheap,show me code 代码有详细注释 主程序 #include "stdafx.h" #include <windows.h> #inc ...
- discuz 不能上传头像提示can not write to the data/tmp folder
# discuz 不能上传头像提示can not write to the data/tmp folder 解释: disucz头像上传不成功,提示data/tmp目录没有写入权限,这里的data/t ...
- hihoCoder week3 KMP算法
题目链接 https://hihocoder.com/contest/hiho3/problems kmp算法 #include <bits/stdc++.h> using namespa ...
- 【NOI 2009】诗人小G
Problem Description 小 \(G\) 是一个出色的诗人,经常作诗自娱自乐.但是,他一直被一件事情所困扰,那就是诗的排版问题. 一首诗包含了若干个句子,对于一些连续的短句,可以将它们用 ...
- Scala语言学习
Scala的程序被编译成Java字节码(生成class文件),所以可以运行在JVM上,并且可以调用Java的类库,兼容Java程序. Scala 是一门多范式(multi-paradigm)的编程语言 ...
- java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not present错误
今天在搭建spring cloud的时候,发现一直报“java.lang.TypeNotPresentException: Type javax.xml.bind.JAXBContext not pr ...
- 封装微信小程序支付
<?php /** * User: Eden * Date: 2019/3/21 * 共有内容 */ namespace Common\Service; use Think\Exception; ...
- 插件写法之脚本运行环境,mac和window检测
(function(root, factroy){ /* * 在这里进行对脚本运行环境的检测判断 * 浏览器中 有window对象 * node.js服务器端 有Global对象 * * IE11 ...
- 哨兵查找法(明解c语言) + 函数式宏
//哨兵法,就是将待查找的元素加入待查找的数组的后面,这样可以提高性能(在数据量很庞大的时候体现出来) #include <stdio.h> #define FAILURE -1 //使用 ...