没啥别的想法,感觉就是搜索,经过原点的抛物线已知两个点就可以求出解析式,在还没有被打下来的两个猪之间随意配对,确定解析式之后标记在这个抛物线下被打下来的猪。
猪也可以单独用一个抛物线打下来。
和之前写斗地主的搜索模式差不多,$TLE60pts$
就是要注意一下精度问题,$get$一个新点:浮点数的判等不能用$==$,可能会有精度误差,只差一点点的情况下可以认为他们是相等的,精度大概就取$EPS=1e-8$
bool dy(double a,double b) {//浮点误差 return Abs(a-b)<EPS; }
1 //暴搜 60pts 2 #include<cstdio> 3 #include<algorithm> 4 #include<vector> 5 #include<cstring> 6 #include<queue> 7 #include<map> 8 #include<iostream> 9 using namespace std; 10 #define ll long long 11 #define INF 0x3f3f3f3f 12 #define N 20 13 #define EPS 1e-8 14 double Abs(double a) 15 { 16 if(a>=0.0) return a; 17 return -a; 18 } 19 bool dy(double a,double b) 20 {//浮点误差 21 return Abs(a-b)<EPS; 22 } 23 int rd() 24 { 25 int f=1,s=0;char c=getchar(); 26 while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();} 27 while(c>='0'&&c<='9'){s=(s<<3)+(s<<1)+(c^48);c=getchar();} 28 return f*s; 29 } 30 int n,m,ans; 31 struct node{ 32 double x,y; 33 }pt[N]; 34 bool vis[N]; 35 int tmp[N],cnt; 36 void dfs(int k)//发射小鸟的次数 37 { 38 if(k>ans) return ; 39 for(int i=1;i<=n;i++) 40 { 41 if(vis[i]) continue; 42 vis[i]=1; 43 for(int j=i+1;j<=n;j++) 44 { 45 if(vis[j]) continue; 46 double x1=pt[i].x,x2=pt[j].x,y1=pt[i].y,y2=pt[j].y; 47 double a=(y1*x2-y2*x1)/(x1*x2*x1-x1*x2*x2); 48 if(a>=0) continue;//vis[j]=1要放在这个后面 否则不构成继续递归的条件也还是标记了 49 double b=(y1*x2*x2-y2*x1*x1)/(x1*x2*x2-x1*x1*x2); 50 //queue<int>Q; 51 //while(!Q.empty()) Q.pop(); 52 cnt=0; 53 vis[j]=1; 54 for(int p=1;p<=n;p++) 55 if(dy(pt[p].x*pt[p].x*a+pt[p].x*b,pt[p].y)) 56 { 57 vis[p]=1; 58 tmp[++cnt]=p; 59 //Q.push(p); 60 } 61 dfs(k+1); 62 vis[j]=0; 63 for(int i=1;i<=cnt;i++) 64 vis[tmp[i]]=0; 65 cnt=0; 66 /*while(!Q.empty()) 67 { 68 int u=Q.front();Q.pop(); 69 vis[u]=0; 70 }*/ 71 } 72 vis[i]=0; 73 } 74 for(int i=1;i<=n;i++) 75 if(!vis[i]) k++; 76 ans=min(ans,k); 77 return ; 78 } 79 int main() 80 { 81 int T=rd(); 82 while(T--) 83 { 84 n=rd(),m=rd(); 85 for(int i=1;i<=n;i++) 86 scanf("%lf %lf",&pt[i].x,&pt[i].y),vis[i]=0; 87 if(n==1) 88 { 89 puts("1"); 90 continue; 91 } 92 if(n==2) 93 { 94 /* 95 x1*x1*x2*a+x1*x2*b=y1*x2 96 x2*x2*x1*a+x2*x1*b=y2*x1 97 (x1*x1*x2-x1*x2*x2)a=y1*x2-y2*x1 98 x1*x2*(x1-x2)a=y1*x2-y2*x1 99 */ 100 if(((pt[1].x*pt[2].x*(pt[1].x-pt[2].x))*(pt[1].y*pt[2].x-pt[2].y*pt[1].x))<0) 101 puts("1"); 102 else puts("2"); 103 continue; 104 } 105 if(m==0||m==2) 106 { 107 ans=n; 108 //for(int i=1;i<=n;i++) 109 // printf("%f %f %d\n",pt[i].x,pt[i].y,vis[i]); 110 dfs(0); 111 printf("%d\n",ans); 112 } 113 if(m==1) 114 { 115 ans=((n+2)/3+1); 116 dfs(0); 117 printf("%d\n",ans); 118 } 119 } 120 return 0; 121 }