我想着用凸包,看看有没有点在凸包里。如果有,ans==3,否则为n。写了好久,都没发现错误。 代码如下
#include<bits/stdc++.h>
using namespace std;
inline int read(){//快读
int x=0,f=1;char ch=getchar();
while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
return x*f;
}
int t,n;
bool jl;//用来记录它里面有没有点
long long b1,b2;//用于函数中的比较
struct na{//这是用来存储点的
int a,b;
}n1[1000001];
//下面用叉积判断在顺时针还是逆时针
bool o(na x,na y){
b1=(x.a-n1[1].a)*(y.b-n1[1].b);
b2=(y.a-n1[1].a)*(x.b-n1[1].b);
if(b1>b2)return true;
if(b1==b2&&x.a<y.a)return true;
//让x坐标小的先
return false;
}
bool f(int x){//也是叉积判断是否在逆时针方向,才符合凸多边形性质
b1=(n1[x-1].a-n1[x-2].a)*(n1[x].b-n1[x-2].b);
b2=(n1[x].a-n1[x-2].a)*(n1[x-1].b-n1[x-2].b);
if(b1<b2)return true;
return false;
}
int main(){
t=read();
for(int i=1;i<=t;i++){
n=read();
for(int j=1;j<=n;j++){
n1[j].a=read(),n1[j].b=read();
if(n1[j].b<n1[1].b){//找到y坐标最小的
swap(n1[j].a,n1[1].a);
swap(n1[j].b,n1[1].b);
}
}
if(n<3)printf("0\n");//没有操作
else if(n==3)printf("3\n");//只有可能是3
else {
jl=false;//每次都刷新
sort(n1+2,n1+n+1,o);//2-n排序
for(int j=3;j<=n;j++){
if(f(j)==true){//true表示不是凸多边形
jl=true;
break;
}
}
if(jl==true)printf("3\n");//其中有点,所以3次操作就能全部覆盖
else printf("%d\n",n);
}
}
return 0;
}