洛谷1378 油滴扩展 dfs进行回溯搜索
题目链接:https://www.luogu.com.cn/problem/P1378
题目中给出矩形的长宽和一些点,可以在每个点放油滴,油滴会扩展,直到触碰到矩形的周边或者其他油滴的边缘,求出剩余面积的最小值,就是求油滴面积的最大值。策略是dfs加上回溯,暴力求解。
代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef unsigned int ui; 4 typedef long long ll; 5 typedef unsigned long long ull; 6 #define pf printf 7 #define mem(a,b) memset(a,b,sizeof(a)) 8 #define prime1 1e9+7 9 #define pi 3.14159265 10 #define prime2 1e9+9 11 #define scand(x) scanf("%lf",&x) 12 #define f(i,a,b) for(int i=a;i<=b;i++) 13 #define scan(a) scanf("%d",&a) 14 #define dbg(args) cout<<#args<<":"<<args<<endl; 15 #define pb(i) push_back(i) 16 #define ppb(x) pop_back(x) 17 #define inf 0x3f3f3f3f 18 #define maxn 10 19 int n; 20 double x1,x2,Y1,y2;//瞄的,y1洛谷编译不了 21 bool vis[maxn]; 22 double dis[maxn][maxn],area=0.0; 23 struct p{ 24 double x,y; 25 double r; 26 }cir[maxn]; 27 double distance(double x1,double Y1,double x2,double y2)//点距 28 { 29 return sqrt((x1-x2)*(x1-x2)+(Y1-y2)*(Y1-y2)); 30 } 31 double get_max(int num)//计算第num个点形成圆的最大半径 32 { 33 double tmp1=min(fabs(cir[num].x-x1),fabs(x2-cir[num].x)); 34 double tmp2=min(fabs(cir[num].y-Y1),fabs(y2-cir[num].y)); 35 double ans=min(tmp1,tmp2); 36 f(i,1,n) 37 { 38 if((i!=num)&&vis[i]) 39 { 40 if(dis[i][num]<=cir[i].r)return 0.0;//一旦被包围在内就不可以扩散 41 ans=min(ans,dis[i][num]-cir[i].r); 42 } 43 } 44 return ans; 45 } 46 void dfs(int dep,double tot) 47 { 48 if(dep==n) 49 { 50 //dbg(area); 51 area=max(area,tot); 52 return; 53 } 54 f(i,1,n) 55 { 56 if(!vis[i]) 57 { 58 vis[i]=true; 59 double R=get_max(i); 60 cir[i].r=R; 61 dfs(dep+1,tot+pi*R*R); 62 vis[i]=false; 63 cir[i].r=0.0;//回溯 64 } 65 66 } 67 } 68 int main() 69 { 70 //freopen("input.txt","r",stdin); 71 //freopen("output.txt","w",stdout); 72 std::ios::sync_with_stdio(false); 73 scan(n); 74 scanf("%lf %lf %lf %lf",&x1,&Y1,&x2,&y2); 75 f(i,1,n) 76 { 77 scand(cir[i].x); 78 scand(cir[i].y); 79 } 80 mem(vis,false); 81 f(i,1,n) 82 f(j,1,n) 83 { 84 dis[i][j]=distance(cir[i].x,cir[i].y,cir[j].x,cir[j].y); 85 } 86 dfs(0,0.0); 87 int ans=(fabs(x1-x2)*fabs(Y1-y2)-area+0.5); 88 pf("%d\n",ans); 89 }
每一个不曾起舞的日子,都是对生命的辜负。