您的位置:首页 > 其它

UVA10012把圆放进矩形的底部求矩形的最短长度

2015-10-02 15:11 246 查看
这题刚开始做的时候,想都没想就直接敲了一个求排列后直接按照每个圆和前一个圆相切的思路算了一遍,

果断WA了,然后想了想,一个很大的圆可以挡到很多小的圆,然后想了很久不知道怎么写了,然而实际上也很简单,

记录每个圆的横坐标,每放一个圆,求这个圆的最长的坐标,即这个圆分别与前面的圆相切的坐标和这个圆的半径比较

取最大值,这样就不需要去确定左边界了,直接可以求出长,就是计算每个点的横坐标加上半径取最大值就行了。

后来想了一下,其实也没必要写递归,就是刚开始的思路求排列就能够解决,只是这里知道圆放置的顺序之后,需要知道每个圆

放置的方式,怎么去知道,就开一个数组存每个圆的横坐标,求这个圆和前面相切的最大横坐标,然后加上半径最大的那个就是

长度,其实这个思路起初WA了之后我有想过,但是可能想多了,我想到了这个圆假如和前面的圆相切之后会不会和这俩个圆之间

的圆相交,或者说这个圆和前面的圆相切的时候会不会不和地面接触等等,然后就没敢敲代码,看来有时候有些东西自己想的不一定就是

对的,最好敲代码去验证。

1:递归代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include<cmath>
#include<climits>
#include<cfloat>
using namespace std;
const int P = 1e9 + 7;
double a[10],c[10],A[10];
int m;
double ans;
int vis[10];
void dfs(int cur)
{
if(cur==m)
{
// for(int i=0;i<m;i++)
//  {
//      double temp=A[i]-c[i];
//     if(temp>0.0)
//          for(int j=0;j<m;j++)
//             c[j]+=temp;
//  }
double res=0.0;
for(int i=0;i<m;i++)
{
double temp=A[i]+c[i];
res=max(temp,res);
}
ans=min(res,ans);
}
for(int i=0;i<m;i++)
{
if(!vis[i])
{
vis[i]=1;
A[cur]=a[i];
c[cur]=a[i];
for(int j=0;j<cur;j++)
{
double temp=c[j]+2*sqrt(A[cur]*A[j]);
c[cur]=max(temp,c[cur]);
}
dfs(cur+1);
vis[i]=0;
}
}
}
int main()
{
int n;
cin>>n;
while(n--)
{
cin>>m;
for(int i=0;i<m;i++)
scanf("%lf",&a[i]);
memset(vis,0,sizeof(vis));
ans=DBL_MAX;
dfs(0);
printf("%.3f\n",ans);
}
return 0;
}


2:全排列代码:

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <map>
#include <set>
#include<cmath>
#include<climits>
#include<cfloat>
using namespace std;
const int P = 1e9 + 7;
double a[10];
int m;
double ans;
int main()
{
int n;
cin>>n;
while(n--)
{
cin>>m;
for(int i=0;i<m;i++)
scanf("%lf",&a[i]);
// memset(vis,0,sizeof(vis));
ans=DBL_MAX;
sort(a,a+m);
do
{
double c[10];
for(int i=0;i<m;i++)
{
c[i]=a[i];
for(int j=0;j<i;j++)
{
double temp=c[j]+2*sqrt(a[i]*a[j]);
c[i]=max(temp,c[i]);
}
}
double res=0.0;
for(int i=0;i<m;i++)
res=max(res,a[i]+c[i]);
ans=min(res,ans);
}while(next_permutation(a,a+m));
//dfs(0);
printf("%.3f\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: