UVA10012把圆放进矩形的底部求矩形的最短长度
2015-10-02 15:11
246 查看
这题刚开始做的时候,想都没想就直接敲了一个求排列后直接按照每个圆和前一个圆相切的思路算了一遍,
果断WA了,然后想了想,一个很大的圆可以挡到很多小的圆,然后想了很久不知道怎么写了,然而实际上也很简单,
记录每个圆的横坐标,每放一个圆,求这个圆的最长的坐标,即这个圆分别与前面的圆相切的坐标和这个圆的半径比较
取最大值,这样就不需要去确定左边界了,直接可以求出长,就是计算每个点的横坐标加上半径取最大值就行了。
后来想了一下,其实也没必要写递归,就是刚开始的思路求排列就能够解决,只是这里知道圆放置的顺序之后,需要知道每个圆
放置的方式,怎么去知道,就开一个数组存每个圆的横坐标,求这个圆和前面相切的最大横坐标,然后加上半径最大的那个就是
长度,其实这个思路起初WA了之后我有想过,但是可能想多了,我想到了这个圆假如和前面的圆相切之后会不会和这俩个圆之间
的圆相交,或者说这个圆和前面的圆相切的时候会不会不和地面接触等等,然后就没敢敲代码,看来有时候有些东西自己想的不一定就是
对的,最好敲代码去验证。
1:递归代码:
2:全排列代码:
果断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; }
相关文章推荐
- 二维码名片的生成与读取
- AndroidUI 布局动画-为列表添加布局动画效果
- POJ2239 Selecting Courses【二部图最大匹配】
- AndroidUI 布局动画-为列表添加布局动画效果
- 【转载】Hibernate 5.0.2 发布
- 拼图
- maven整合s2sh截图
- 【用python实现《统计学习方法》】之决策树C4.5/ID3
- 函数后面加一个const的作用
- DM6437平台开发-----程序烧写1
- 支付宝登陆界面(手势解锁的实现)
- 弹性布局flex
- BASE64Encoder问题类
- 今天开始学汇编,遇到不懂的希望大家可以一起讨论
- 关于default constructor的误解
- C++ Qt GUI 将Qt设计师生成的**.ui文件转为ui_**.h
- 等待唤醒机制
- 选择什么样的前端框架
- cloudera manager和cdh离线安装
- Swap Nodes in Pairs and Reverse Nodes in k-Group