大概算是第一道的计算几何题??
我们可以发现给出的三个量相加等于一,别跟我说样例,所以可以忽略一项
然后我们可以发现,如果要混合出一样东西,假设是x1,y1.x2,y2混合出x3,y3
(x1<x2,y1<y2)那么可以发现x1<x3<x2&&y1<y3<y2
所以题目就是要找一些点这些点连出来的多边形可以包含所有点
这样就是个凸包了,然后floyed跑个最短路
我的注释多详细
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<cstdio>
#define eps 1e-10
#define inf 100000000
using namespace std;
struct P{
double x,y;
};
P a[505],b[505];
int dis[505][505],mp[505][505],n,m;
double operator*(P a,P b){
return a.x*b.y-a.y*b.x;
}//求点积
P operator-(P a,P b){
P t;
t.x=a.x-b.x;
t.y=a.y-b.y;
return t;
}//点的差求出向量
bool col(P x,P y){
if(x.x>y.x){
swap(x,y);
}
for(int i=1;i<=m;i++){
if(b[i].x<x.x||b[i].x>y.x){
return 0;
}
}//判断是否都在x,y的线段上
if(x.y>y.y){
swap(x,y);
}
for(int i=1;i<=m;i++){
if(b[i].y<x.y||b[i].y>y.y){
return 0;
}
}//判断是否都在x,y的线段上
return 1;
}
int jud(P x,P y){
int c1=0,c2=0;
for(int i=1;i<=m;i++){
double t=(y-x)*(b[i]-x);//点积来计算两个向量的位置关系
if(t>eps){
c1++;
}//在顺时针位置
if(t<-eps){
c2++;
}//逆时针
if(c1*c2){
return 0;
}//两边都有的话,直接不连边
}
if(!c1&&!c2&&col(x,y)){
cout<<2<<endl;
return -1;
}//如果正好在这条线上,并且所有点都可以被包住,直接输出2
if(c1){
return 1;
}//如果只有顺时针
if(c2){
return 2;
}//只有逆时针
return 3;//第五种情况就是所有点在同一直线但是x,y并不包含所有点
}
void floyd(){
int ans=inf;
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
if(dis[i][k]<inf){
for(int j=1;j<=n;j++){
dis[i][j]=min(dis[i][j],dis[i][k]+dis[k][j]);
}
}
}
}//floyed求一下传递闭包,最短路
for(int i=1;i<=n;i++){
ans=min(ans,dis[i][i]);
}//算一算以一个点为顶点的传递闭包的最短路
if(ans==inf||ans<=2){
cout<<"-1"<<endl;
}else{
printf("%d",ans);
}
}
void solve(){
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
int flag=jud(a[i],a[j]);
if(flag==-1){
return;
}//已经包住了,返回
if(flag==1){
dis[i][j]=1;//都在左侧
}else if(flag==2){
dis[j][i]=1;//都在右侧
}else if(flag==3){
dis[i][j]=dis[j][i]=1;//都在线上
}
}
}
floyd();//求传递闭包
}
bool spj(){
for(int i=1;i<=n;i++){
if(fabs(a[i].x-a[1].x)>eps||fabs(a[i].y-a[1].y)>eps){
return 0;
}
}
for(int i=1;i<=m;i++){
if(fabs(b[i].x-a[1].x)>eps||fabs(b[i].y-a[1].y)>eps){
return 0;
}
}
puts("1");
return 1;
}
int main(){
memset(dis,127/3,sizeof(dis));
cin>>n>>m;
double K;
for(int i=1;i<=n;i++){
cin>>a[i].x>>a[i].y>>K;
}//这个K。。。。
for(int i=1;i<=m;i++){
cin>>b[i].x>>b[i].y>>K;
}//这个K。。。。
if(spj()){
return 0;
}
solve();
return 0;
}
/*
in:
3 2
0.25 0.25 0.5
0 0.6 0.4
1 0 0
0.7 0.1 0.2
0.85 0.05 0.1
out:
2
*/