SOJ 1012 Stacking Cylinders

来源:互联网 发布:java工作心得体会 编辑:程序博客网 时间:2024/05/14 11:47

题目传送门在此

似乎是道纯几何题,图解如下,这样子摞出来的一堆圆,给出最下一层的所有圆心的横坐标,半径均为1,要求出最顶端的圆的圆心

每一层比下一层少一个,也就是下层每两个夹一个,我们可以看出下两个和上一个的圆心组成一个腰为2的等腰三角形。可以根据下两个的坐标推出一个几何关系。


定义一个坐标结构体方便计算,算坐标的函数写得略臃肿,不过是根据推断过程一步步来的.

#include <cstdio>#include <algorithm>#include <cmath>#include <iostream>using namespace std;struct coordinate {    double x;    double y;};bool cmp(const coordinate& c1, const coordinate& c2) {    return (c1.x < c2.x);}coordinate cal(coordinate c1, coordinate c2) {    double x1 = c1.x;    double x2 = c2.x;    double y1 = c1.y;    double y2 = c2.y;    double midX = (x1 + x2) * 0.5;    double midY = (y1 + y2) * 0.5;//中点     double k = (y1 - y2) / (x1 - x2);//下两点连线斜率     if (y1 == y2) {        coordinate result;        result.x = midX;        double height = sqrt(4 - (fabs(x2 - x1) * 0.5) * (fabs(x2 - x1) * 0.5));        result.y = y1 + height;        return result;//持平就直接算     } else {        k = -1.0 / k;//算垂直平分线斜率         double len = sqrt(16.0 - (y1 - y2) * (y1 - y2) - (x1 - x2) * (x1 - x2)) * 0.5;        double vx, vy;        if (k < 0.0) {            vx = -1.0 / sqrt(k * k + 1);            vy = -k / sqrt(k * k + 1);        } else {            vx = 1.0 / sqrt(k * k + 1);            vy = k / sqrt(k * k + 1);        }        vx *= len;        vy *= len;//算中点指向目标点的向量坐标        double tarX = midX + vx;        double tarY = midY + vy;         coordinate result;        result.x = tarX;        result.y = tarY;        return result;    }}int main() {    int n;    while ((cin >> n) && n) {        coordinate all[11];        for (int i = 0; i < n; ++i) {            cin >> all[i].x;            all[i].y = 1.0;        }        sort(all, all + n, cmp);        int k = n;        while (k > 1) {            for (int i = 0; i < k - 1; ++i) {                all[i] = cal(all[i], all[i + 1]);            }            --k;        }        printf("%.4f %.4f\n", all[0].x, all[0].y);    }    return 0;}                                 


0 0
原创粉丝点击