愤怒的小鸟——去年的题今年才做完
先预处理每两只猪构成的抛物线可以打到的猪。然后枚举当前状态是多打一头猪还是多打一条抛物线。开始因为把手写abs 写成了return x>0?x:-1; 而无法正常预处理,盯着代码看了一个早上,实际上问题根本不在后面计算部分。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; const int N=20,INF=0x3f3f3f3f; const double DIF=1e-8; int n,m,FULL,f[(1<<N)],bird[N][N]; double x[N],y[N]; bool equal(double x,double y){return abs(x-y)<=DIF;} int main(){ int T;cin>>T; while(T--){ memset(x,0,sizeof x);memset(y,0,sizeof y);memset(f,0x3f,sizeof f); memset(bird,0,sizeof bird); cin>>n>>m; FULL=(1<<n)-1; for(int i=1;i<=n;i++)cin>>x[i]>>y[i]; for(int i=1;i<n;i++) for(int j=i+1;j<=n;j++) if(!equal(x[i],x[j])){ double a=(y[i]/x[i]-y[j]/x[j])/(x[i]-x[j]); if(a>=0)continue; double b=y[i]/x[i]-a*x[i]; for(int k=1;k<=n;k++) if(equal(a*x[k]+b,y[k]/x[k])) bird[i][j]=bird[i][j]|(1<<(k-1)); } f[0]=0; for(int k=0;k<=FULL;k++) for(int i=1;i<=n;i++) if(!(k&(1<<(i-1)))){ for(int j=i;j<=n;j++) if(i==j) f[k|(1<<(j-1))]=min(f[k|(1<<(j-1))],f[k]+1); else if(!equal(x[i],x[j])) f[k|bird[i][j]]=min(f[k|bird[i][j]],f[k]+1); break; } cout<<f[FULL]<<endl; } return 0; }
Vijos 691ms

浙公网安备 33010602011771号