POJ 2194 Stacking Cylinders(两圆相切求圆心坐标)
http://poj.org/problem?id=2194
题意: POJ2850 ZOJ2403
有多个圆堆叠在一起,它们被成了好多层.其中最下面那层有n个圆,从下往上每层圆依次减少1个.且上层的圆一定是与下层两个相邻的圆相切的.给定你最下层n个圆的圆心坐标,要你输出最上一层的圆心坐标.
分析:
大体思路是通过最下层的圆心坐标来依次递推出上一层圆心的坐标即可. 由于每个上层圆一定是由下层两个相邻的圆相切堆叠起来的,所以有下图:
总的来说,我们只需要能根据下面的两个圆心坐标和圆半径算出上面的那个圆心坐标即可最终推出最上点坐标.
AC代码:
//用C++提交,G++提交有打印double的BUG
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
const double eps=1e-10;
const int maxn=10+5;
struct Point
{
double x,y;
Point(){}
Point(double x,double y):x(x),y(y){}
};
typedef Point Vector;
Vector operator-(Point A,Point B)
{
return Vector(A.x-B.x,A.y-B.y);
}
Vector operator+(Vector A,Vector B)
{
return Vector(A.x+B.x,A.y+B.y);
}
Vector operator*(Vector A,double p)
{
return Vector(A.x*p, A.y*p);
}
double Dot(Vector A,Vector B)
{
return A.x*B.x+A.y*B.y;
}
double Length(Vector A)
{
return sqrt(Dot(A,A));
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
//向量A逆时针旋转特定角度,该角度对应的正弦和余弦值
Vector Rotate(Vector A,double sinv,double cosv)
{
return Vector(A.x*cosv-A.y*sinv, A.x*sinv+A.y*cosv);
}
Point GetLineIntersection(Point P,Vector v,Point Q,Vector w)
{
Vector u=P-Q;
double t=Cross(w,u)/Cross(v,w);
return P+v*t;
}
/***以上为刘汝佳模板***/
//根据底部的两圆心A和B来计算上层圆心,假设所求圆心为P点
Point get_upper_point(Point A,Point B)
{
double len_AB=Length(A-B);
double cosv= (len_AB/2)/2.0;
double sinv=sqrt(1-cosv*cosv);
Vector PA=Rotate(B-A,sinv,cosv);//旋转后的向量
Vector PB=Rotate(A-B,-sinv,cosv);//旋转后的向量
return GetLineIntersection(A,PA,B,PB);
}
int main()
{
int n;
double x[maxn];
Point P[maxn][maxn];
while(scanf("%d",&n)==1 && n)
{
for(int i=0;i<n;++i) scanf("%lf",&x[i]);
sort(x,x+n);
for(int i=0;i<n;++i)
P[0][i]=Point(x[i],1.0);
for(int i=1;i<n;++i)//从第1层开始递推该层所有圆心坐标
{
for(int j=0;j<n-i;++j)
P[i][j]=get_upper_point(P[i-1][j],P[i-1][j+1]);
}
printf("%.4lf %.4lf\n",P[n-1][0].x,P[n-1][0].y);
}
return 0;
}
分享到:
相关推荐
poj 1972 Dice Stacking.md
POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类POJ分类
poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题报告poj 解题...
北大POJ1804-Brainman【借助Mergesort求逆序数O(nlogn)】
POJ第1861题源码 POJ第1861题源码 POJ第1861题源码
北大POJ1159-Palindrome 解题报告+AC代码
poj分类poj分类poj分类poj分类
poj 3414解题报告poj 3414解题报告poj 3414解题报告poj 3414解题报告
C语言 poj npu 西工大 C语言Poj答案全完整打包,给有需要的朋友
poj 1012解题报告poj 1012解题报告poj 1012解题报告poj 1012解题报告
poj 2329解题报告poj 2329解题报告poj 2329解题报告poj 2329解题报告
poj 1659解题报告poj 1659解题报告poj 1659解题报告poj 1659解题报告
POJ3308-Paratroopers 【二分图顶点覆盖->最小割->最大流->Dinic算法求解】 解题报告+AC代码 http://hi.csdn.net/!s/WKVPR0 ----> 我的所有POJ解题报告 ...
POJ1503解答 POJ1503解答,正确答案(已通过POJ)
北大POJ2002-Squares 解题报告+AC代码
POJ1048,加强版的约瑟夫问题 难度中等
POJ1083的代码,POJ1083的代码,POJ1083的代码
poj 百练 题目分类 poj 百练 题目分类
poj 1001答案
poj openjudge 1024题 两倍源代码提交ac