sicily 1012. Stacking Cylinders & 1206. Stacking Cylinders
Description
Cylinders (e.g. oil drums) (of radius 1 foot) are stacked in a rectangular bin. Each cylinder on an upper row rests on two cylinders in the row below. The cylinders in the bottom row rest on the floor. Each row has one less cylinder than the row below.
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
Each data set will appear in one line of the input. An input line consists of the number, n, of cylinders on the bottom row followed by n floating point values giving the x coordinates of the centers of the cylinders (the y coordinates are all 1.0 since the cylinders are resting on the floor (y = 0.0)). The value of n will be between 1 and 10 (inclusive). The end of input is signaled by a value of n = 0. The distance between adjacent centers will be at least 2.0 (so the cylinders do not overlap) but no more than 3.4 (cylinders at level k will never touch cylinders at level k – 2).
Output
The output for each data set is a line containing the x coordinate of the topmost cylinder rounded to 4 decimal places, a space and the y coordinate of the topmost cylinder to 4 decimal places. Note: To help you check your work, the x-coordinate of the center of the top cylinder should be the average of the x-coordinates of the leftmost and rightmost bottom cylinders.
Sample Input
Copy sample input to clipboard
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 |
分析:
1. 首先,根据题意,程序的输入就是最底层的球,然后在其上面每层都比下一层少一个球, 2. 可以证明,在底层的球每一个和其底层第一个球的横坐标的中点不为都有一个其上面球的横坐标,最后一个球对应最上面一个球,如图: 也就是利用等腰三角形来求解。
其实应该说首先要证明第一行的球其从第二个开始,每一个和第一个求,上一层的最左边球都会构成一个等腰三角形,根据这个性质去做就ok,
不要把题意理解为输入的球就是所有球,我开始就是这么理解的所以和一个小伙伴一起想了很久想了一个很复杂的办法,因为那样的话根本不知道分层情况,当然还是利用等腰三角形去解。然后在去饭堂吃饭的时候突然想明白了,,,
code:
#include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cmath> #include <cstdio> using namespace std; #define RADIUS 2.0 int main(int argc, char const *argv[]) { vector<double> xValue; int pointNum; double x, y; while (cin >> pointNum && pointNum != 0) { xValue.resize(pointNum); y = RADIUS / 2; for (int i = 0; i != pointNum; ++i) { cin >> xValue[i]; } sort(xValue.begin(), xValue.end()); x = xValue[0]; for (int i = 1; i != pointNum; ++i) { double preX = x; x = (xValue[i] - xValue[0]) / 2 + xValue[0]; // 上一层的最左边球的横坐标,注意这个上一层是递增的 preX = x - preX; y = sqrt(pow(RADIUS, 2) - pow(preX, 2)) + y; // 上一层的最左边球的纵坐标,注意这个上一层是递增的,利用勾股定理 } printf("%.4lf %.4lf\n", x, y); } return 0; }
至于 1206. Stacking Cylinders 这道题,其实方法是完全一样的,但是输入和输出格式都不一样,我看了好久才发现输入格式不一样。。。
#include <iostream> #include <vector> #include <algorithm> #include <cstring> #include <cmath> #include <cstdio> using namespace std; #define RADIUS 2.0 int main(int argc, char const *argv[]) { vector<double> xValue; int pointNum; double x, y; int testNum; cin >> testNum; for (int i = 1; i <= testNum; ++i) { cin >> pointNum; xValue.resize(pointNum); y = RADIUS / 2.0; for (int i = 0; i != pointNum; ++i) { cin >> xValue[i]; } sort(xValue.begin(), xValue.end()); x = xValue[0]; for (int i = 1; i != pointNum; ++i) { double preX = x; x = (xValue[i] - xValue[0]) / 2.0 + xValue[0]; preX = x - preX; y += sqrt(pow(RADIUS, 2.0) - pow(preX, 2.0)); } printf("%d: %.4lf %.4lf\n", i, x, y); } return 0; }