Time Limit: 1000MS | Memory Limit: 65536K | |
Total Submissions: 1069 | Accepted: 571 |
Description
![](http://poj.org/images/2194_1.jpg)
This problem is to write a program to compute the location of the center of the top cylinder from the centers of the cylinders on the bottom row. Computations of intermediate values should use double precision.
Input
Output
Sample Input
4 1.0 4.4 7.8 11.2 1 1.0 6 1.0 3.0 5.0 7.0 9.0 11.0 10 1.0 3.0 5.0 7.0 9.0 11.0 13.0 15.0 17.0 20.4 5 1.0 4.4 7.8 14.6 11.2 0
Sample Output
6.1000 4.1607 1.0000 1.0000 6.0000 9.6603 10.7000 15.9100 7.8000 5.2143
Source
题目概述:一个箱子里一堆球,求最上面一个的坐标。
方法:给出两个球坐标,再计算出顶上第三个球的坐标。然后不断递推上去。
思路:二维数组存储每行每列圆的坐标,二维数组元素系自定义结构体类型包括横纵坐标。
输入最底层坐标,即对数组 e[n][i] 赋值。并根据最底层圆的横坐标由小到大排序。
两重循环由底向上求得上一层圆的坐标,即根据底层相邻的两个圆的坐标求出上一层位于这两个圆之间一个圆的坐标。
具体求法:
由于or 长度为半径的二倍,所以只需在线段 op 上截取 or 的长度 oq 使得 oq 绕 o 点旋转 一定角度便可求出 r 点坐标。
所以一要求q点坐标,二要求角rop。 求坐标时可用三角形相似。球角度可用(op/(2*or))的反余弦函数。
代码:
#include <iostream>
#include <cmath>
#include <stdio.h>
#include <algorithm>
#define R 1.0
using namespace std;
int n;
int i,j;
struct E
{
double x;
double y;
};
E e[15][15];
E rotate(E o, double alpha, E p)
{
E tmp;
p.x-=o.x; p.y -= o.y;
tmp.x = p.x * cos(alpha) - p.y * sin(alpha) +o.x;
tmp.y = p.y * cos(alpha) + p.x * sin(alpha) +o.y;
return tmp;
}
int cmp(E a,E b)
{
return a.x<b.x;
}
int main()
{
while(cin>>n && n)
{
for(i=0;i<n;i++)
{
cin>>e[n][i].x;
e[n][i].y=1.0;
}
sort(e[n],e[n]+n,cmp);
for(i=n-1;i>=1;i--)
{
for(j=0;j<i;j++)
{
double x1,x2,x3,y1,y2,y3,d;
x1=e[i+1][j].x; y1=e[i+1][j].y;
x2=e[i+1][j+1].x; y2=e[i+1][j+1].y;
d=double(sqrt((y2-y1)*(y2-y1)+(x2-x1)*(x2-x1)));
x3=2.0*(x2-x1)/d+x1;
y3=2.0*(y2-y1)/d+y1;
double l=2.0*R;
double o=acos(d/(l*2.0));
E e1;
e1.x=x3;
e1.y=y3;
e[i][j]=rotate(e[i+1][j],o,e1);
}
}
printf("%.4f %.4f\n",e[1][0].x,e[1][0].y);
}
return 0;
}