计算几何之所以难学 就是因为太抽象了 不够直观 而且情况很多 很繁琐 甚至有一些东西不清不楚。。

这道题注意到题目中的描述 一个鸽子在两个点所连直线上也算。

通过看题解 发现这个地方并非直线而是线段 这不是明摆着坑人..

先考虑m<=10的做法 可以想到爆搜 然后 就利用直线 点 三角形来判断复杂度\(2^m\cdot m^3\cdot n\) 期望得分30.

其中直线判断的时候 严谨一点是 如果在直线上再判断len的大小 可是当时考试的时候发现题目中的这句话了所以就没管。

三角形 的话容易转圈叉积来判 三个叉积同方向就说明在三角形中。

code bf:
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 1000000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define P 1000000007
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-8
#define sq sqrt
#define mod 1000000007
#define S second
#define F first
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=300010,maxn=10000010;
int n,m,cnt,ans=INF;
int a[MAXN];
struct wy
{
int x,y;
inline bool operator ==(wy a)
{
return x==a.x&&y==a.y;
}
inline wy operator -(wy a)
{
return (wy){x-a.x,y-a.y};
}
}t[MAXN],w[MAXN];
inline int judge(wy a,wy b)
{
ll ww=(ll)a.x*b.y-(ll)b.x*a.y;
if(!ww)return 0;
return ww>0?1:-1;
}
int b[MAXN];
inline void dfs(int x,int v)
{
if(v>=ans)return;
if(x==m+1)
{
rep(1,n,w1)
{
int flag=0;
rep(1,v,i)
{
if(t[w1]==w[b[i]]){flag=1;break;}
rep(i+1,v,j)
{
if(t[w1]==w[b[j]]){flag=1;break;}
//判断点是否在一条直线上:
if(!judge(w[b[i]]-w[b[j]],t[w1]-w[b[j]])){flag=1;break;}
rep(j+1,v,k)
{
if(t[w1]==w[b[k]]){flag=1;break;}
//判断点是否在一个三角形中 要求叉积的值都相等.
int c1=judge(w[b[i]]-w[b[j]],t[w1]-w[b[j]]);
int c2=judge(w[b[k]]-w[b[i]],t[w1]-w[b[i]]);
int c3=judge(w[b[j]]-w[b[k]],t[w1]-w[b[k]]);
if(c1==c2&&c2==c3){flag=1;break;}
}
if(flag)break;
}
if(flag)break;
}
if(!flag)return;
}
ans=v;
return;
}
b[v+1]=x;
dfs(x+1,v+1);
dfs(x+1,v);
}
int main()
{
freopen("lo.in","r",stdin);
freopen("lo.out","w",stdout);
get(n);get(m);
rep(1,n,i)
{
int get(x),get(y);
t[i]=(wy){x,y};
}
rep(1,m,i)
{
int get(x),get(y);
w[i]=(wy){x,y};
}
if(m<=10)
{
dfs(1,0);
put(ans==INF?-1:ans);
return 0;
}
put(-1);
return 0;
}

值得注意的是叉积的时候要开longlong. 不然痛失30分。

进一步考虑 如果是线段而不是直线的话 那么其实由暴力来看就是一些三角形 一些直线 一些点构成了答案。

这些东西其实只需要把鸽子所围成的凸包上的点都包含其实相当于包含了整体。因为这些点之间连边形成的一定也是一个凸多边形。

其实就是要求找到一个凸包包含另外一个凸包。

这个时候 考虑每一个点 然后向原凸包中发出两条切线显然切线一侧的可以是后继 然后连边。

最后跑floyd即可。最后从i到i的环的最小值就是答案了。

分析出问题的关键还是从答案的角度考虑:显然答案的点一定不在原凸包内 那只能在凸包外 此时找凸包外一点 然后寻找下一点 其实就是做切线问题了。

值得一提的是 该特判的特判好 不过没有特判一个点的情况 且是在线段的情况下的。

code sol:
//#include<bits\stdc++.h>
#include<iostream>
#include<iomanip>
#include<cstdio>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<cctype>
#include<cstdlib>
#include<queue>
#include<deque>
#include<stack>
#include<vector>
#include<algorithm>
#include<utility>
#include<bitset>
#include<set>
#include<map>
#define ll long long
#define db double
#define INF 100000000
#define ldb long double
#define pb push_back
#define put_(x) printf("%d ",x);
#define get(x) x=read()
#define gt(x) scanf("%d",&x)
#define gi(x) scanf("%lf",&x)
#define put(x) printf("%d\n",x)
#define putl(x) printf("%lld\n",x)
#define gc(a) scanf("%s",a+1)
#define rep(p,n,i) for(RE int i=p;i<=n;++i)
#define go(x) for(int i=lin[x],tn=ver[i];i;tn=ver[i=nex[i]])
#define fep(n,p,i) for(RE int i=n;i>=p;--i)
#define vep(p,n,i) for(RE int i=p;i<n;++i)
#define pii pair<int,int>
#define mk make_pair
#define RE register
#define gf(x) scanf("%lf",&x)
#define pf(x) ((x)*(x))
#define uint unsigned long long
#define ui unsigned
#define EPS 1e-9
#define sq sqrt
#define mod 998244353
#define S second
#define F first
#define pf(x) ((x)*(x))
using namespace std;
char buf[1<<15],*fs,*ft;
inline char getc()
{
return (fs==ft&&(ft=(fs=buf)+fread(buf,1,1<<15,stdin),fs==ft))?0:*fs++;
}
inline int read()
{
RE int x=0,f=1;RE char ch=getc();
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getc();}
while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getc();}
return x*f;
}
const int MAXN=100010,maxn=510;
int n,m;
int f[maxn][maxn];
struct Vec
{
db x,y;
bool operator ==(Vec b){return fabs(x-b.x)<=EPS&&fabs(y-b.y)<=EPS;}
db operator %(Vec b){return x*b.y-y*b.x;}
inline void ni(){x=-x;y=-y;}
Vec operator -(Vec b){return (Vec){x-b.x,y-b.y};}
}a[MAXN],b[maxn];
typedef Vec P;
inline int pd(db x,db y){return fabs(x-y)<=EPS?0:x<y?-1:1;}
int main()
{
freopen("1.in","r",stdin);
get(n);get(m);
memset(f,0x3f,sizeof(f));
rep(1,n,i)get(a[i].x),get(a[i].y);
rep(1,m,i)get(b[i].x),get(b[i].y);
rep(1,m,i)
{
int mxid=0,mnid=0,id1=0,id2=0;
P mx,mn,tmp;db v1,v2;
rep(1,n,j)
{
if(a[j]==b[i])continue;
tmp=a[j]-b[i];
db ww=tmp%(a[1]-b[i]);
if(mxid==0||pd(tmp%mx,0)<0)mx=tmp,mxid=j;
if(mnid==0||pd(tmp%mn,0)>0)mn=tmp,mnid=j;
if(id1==0||v1<ww)id1=j,v1=ww;
if(id2==0||v2>ww)id2=j,v2=ww;
}
if(pd((a[id1]-b[i])%(a[id2]-b[i]),0)<0)continue;
mx.ni();
rep(1,m,j)
{
if(i==j)continue;
tmp=b[j]-b[i];
if(pd(mn%tmp,0)<=0&&pd(tmp%mx,0)<=0)f[i][j]=1;
}
}
rep(1,m,k)rep(1,m,i)rep(1,m,j)f[i][j]=min(f[i][j],f[i][k]+f[k][j]);
int ans=INF;rep(1,m,i)ans=min(ans,f[i][i]);
put(ans==INF?-1:ans);
return 0;
}

7.1 NOI模拟赛 凸包套凸包 floyd 计算几何的更多相关文章

  1. 【2019.3.20】NOI模拟赛

    题目 这里必须标记一下那个傻逼问题,再不解决我人就没了! 先放一个 $T3$ $20$ 分暴力 #include<bits/stdc++.h> #define rep(i,x,y) for ...

  2. NOI模拟赛 Day1

    [考完试不想说话系列] 他们都会做呢QAQ 我毛线也不会呢QAQ 悲伤ING 考试问题: 1.感觉不是很清醒,有点困╯﹏╰ 2.为啥总不按照计划来!!! 3.脑洞在哪里 4.把模拟赛当作真正的比赛,紧 ...

  3. 6.28 NOI模拟赛 好题 状压dp 随机化

    算是一道比较新颖的题目 尽管好像是两年前的省选模拟赛题目.. 对于20%的分数 可以进行爆搜,对于另外20%的数据 因为k很小所以考虑上状压dp. 观察最后答案是一个连通块 从而可以发现这个连通块必然 ...

  4. 【2018.12.10】NOI模拟赛3

    题目 WZJ题解 大概就是全场就我写不过 $FFT$ 系列吧……自闭 T1 奶一口,下次再写不出这种 $NTT$ 裸题题目我就艹了自己 -_-||| 而且这跟我口胡的自创模拟题 $set1$ 的 $T ...

  5. NOI 模拟赛 #2

    得分非常惨惨,半个小时写的纯暴力 70 分竟然拿了 rank 1... 如果 OYJason 和 wxjor 在可能会被爆踩吧 嘤 T1 欧拉子图 给一个无向图,如果一个边集的导出子图是一个欧拉回路, ...

  6. NOI模拟赛Day5

    T1 有and,xor,or三种操作,每个人手中一个数,求和左边进行某一种运算的最大值,当t==2时,还需要求最大值的个数. test1 20% n<=1000 O(n^2)暴力 test2 2 ...

  7. NOI模拟赛Day4

    看到成绩的时候我的内心** woc第一题写错了呵呵呵呵呵呵呵呵 人不能太浪,会遭报应的** ------------------------------------------------------ ...

  8. NOI模拟赛Day3

    终于A题啦鼓掌~开心~ 开考看完题后,觉得第二题很好捏(傻叉上线 搞到十一点准备弃疗了然后突然发现我会做第一题 于是瞎码了码,就去准备饭票了... 好了,停止扯淡(就我一个我妹子每天不说话好难受QAQ ...

  9. NOI模拟赛Day2

    深深的感受到了自己的水 ---------------------------------------------------------------------------------------- ...

随机推荐

  1. Java基础-线程与并发1

    线程与并发 Thread 基本概念 程序: 一组计算机能识别和执行的指令 ,是静态的代码. 进程: 程序的一次运行活动, 运行中的程序 . 线程: 进程的组成部分,它代表了一条顺序的执行流. 进程线程 ...

  2. videojs兼容ie8

    从网上找到很多这个videojs兼容ie8的解决方案,一个一个的试,最后发现没有一个是靠谱的.我好无奈啊…… 先看图(ie上访问必须是线上地址) 看代码: <!DOCTYPE html> ...

  3. elasticsearch集群配置 (Tobe Continue)

    elasticsearch集群配置 (Tobe Continue)   准备 首先需要在每个节点有可以正常启动的单节点elasticsearch   elasticsearch集群配置仅需要在elas ...

  4. AT2272 [ARC066B] Xor Sum 题解

    题目连接:传送门 分析 这道题只看题目中给的样例是找不出规律的 所以我们可以打一下表 1, 2, 4, 5, 8, 10, 13, 14, 18 如果你还是没有看出什么规律的话,我们可以从OEIS上搜 ...

  5. ASP.NET网页请求以及处理全过程(反编译工具查看源代码)

    本文是自己查看源码后的个人总结,不保证其准确性.大家可作为参考. 浏览器和服务器之间的通信. 当敲一个域名到浏览器上面,然后回车的时候,如:http://www.baidu.com/index.asp ...

  6. Python OpenCV的绘图功能简介

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者:大Z 在图像中我们经常需要用到将某个局部特征画出来,比如物体检测,物 ...

  7. LintCode笔记 - 145.大小写转换 - 极简之道 - 最短代码

    这道题目一眼就能看出是送分题,当然在这里也不谈高难度的实现逻辑,肯定有同学会想直接用自带函数实现不就可以了吗? 对的,就是这么简单,然而今天的重点是如何把代码简写到最短. 本文章将带你把代码长度从 一 ...

  8. 并发编程之synchronized锁(一)

    一.设计同步器的意义 多线程编程中,有可能会出现多个线程同时访问同一个共享.可变资源的情况,这个资源我们称之其为临界资源:这种资源可能是:对象.变量.文件等. 共享:资源可以由多个线程同时访问 可变: ...

  9. OSCP Learning Notes - Exploit(3)

     Modifying Shellcode 1. Search “vulnserver exploit code” on the Internet. Find the following website ...

  10. ssh配置、vscode使用及常用扩展

    1.ssh配置 1.1 进入命令行 win + r  > cmd 1.2 输入如下代码直接回车即可生成ssh  ssh-keygen -t rsa -C "xxx@qq.com&quo ...