题目传送门

没啥别的想法,感觉就是搜索,经过原点的抛物线已知两个点就可以求出解析式,在还没有被打下来的两个猪之间随意配对,确定解析式之后标记在这个抛物线下被打下来的猪。

猪也可以单独用一个抛物线打下来。

和之前写斗地主的搜索模式差不多,$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 }
Code

相关文章:

  • 2021-11-30
  • 2021-06-21
  • 2021-05-23
  • 2021-12-03
  • 2021-05-28
  • 2021-12-25
猜你喜欢
  • 2022-01-16
  • 2021-07-15
  • 2022-01-05
  • 2022-12-23
  • 2022-12-23
  • 2021-10-23
  • 2021-10-18
相关资源
相似解决方案