ICPC North Central NA Contest 2020 I. Staggering to the Finish

ICPC North Central NA Contest 2020
I. Staggering to the Finish
题目描述
An oval track and field racing track consists of two parallel straightaway sections connected by two semicircles,depicted in figure 1. Footraces run in the counterclockwise direction, ending at a common finish line located along the lower straightaway. For races that exceed the length of a single straightaway, starting lines must be staggered backwards, in the clockwise direction, from the finish line. The staggered starting lines must account for the curve of the semicircles and the widths of each running lane.
在这里插入图片描述
There are international standards for oval track dimensions. Unfortunately, the available area for a track doesn’t always hold a standard track. Given the dimensions of the track and the length of the race, your team is to write a program to ensure equal race lengths by computing the staggered starting line positions.
The total distance of a race for any given lane is computed from the line of running. The line of running is an unmarked line to the right of the lane’s inside marker (as seen from the counterclockwise direction). See figure 2. For the innermost lane (lane 1) the line of running is usually farther from the lane marker than for the remaining lanes.
The track is mapped to an (x, y) coordinate system with (0, 0) at the center of the track. See figure 1.
输入
The first line of input to your program contains seven values, N R S W F L1 L2 , separated by whitespace, describing the geometry of a track, where:
• N is the integer number of lanes. (1 ≤ N ≤ 9)
• R is the inner radius of lane 1, a real number in meters. See figure 1. (1.0 ≤ R ≤ 100.0)
• S is the length of the straightaway, a real number in meters. See figure 1. (1.0 ≤ S ≤ 200.0)
在这里插入图片描述
• W is the width of each lane, a real number in meters. See figure 2. (0.5 ≤ W ≤ 3.0)
• F is the x-coordinate of the finish line, measured from the centerline in figure 1, a real value in meters. The finish line will always be in the lower (negative y) half of the track. (|F| ≤ S/2)
• L1 is the offset from the inner radius of lane 1 to the line of running for lane 1, a real number in meters. See figure 2. (0 ≤ L 1 < W)
• L2 is the offset from the inner radius to the lines of running for lanes 2 and higher. See figure 2. (0 ≤ L 2 < W)
The remaining lines until end-of-file specify D, the distance of a race, one race per line, a real number in meters.
(1.0 ≤ D < 410.0.) There will be at most 100 distances D in input.

输出
Your program is to print a series of values for each race distance, separated from each other by spaces and/or newlines.
Print the race distance first, followed by the (x, y) coordinates of the staggered starting line locations in lane number order. Express all values in meters. The (x, y) coordinate is the innermost point of a lane, NOT the line of running.
Treat each lane marker (straightaway or radius) as a zero-width line. International standards require that the values be within 0.001 meters of the exact answer.
样例输入 Copy
4 36.5 84.39 1.22 40.0 0.30 0.20
200.0
400
样例输出 Copy
200.000 -40.0006 36.5000 -43.5119 37.6970 -47.3108 38.6025 -51.0664 39.1679
400.000 40.0012 -36.5000 46.9998 -37.4127 54.4292 -36.9682 61.4438 -35.2464

题意: 给出一些参数, 以操场中心为原点建立直角坐标系, 给定终点坐标和赛程, 求每个跑道起点坐标.
没什么算法, 用一点初高中数学知识, 模拟就完事了, 队友很细心, 赞

代码冗余的部分大家删删就好…

#define IO ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
//#pragma comment(linker,"/STACK:102400000,102400000")
#define REP(i,a,b) for(RE i=(a);i<=(b);i++)
#define PER(i,a,b) for(RE i=(a);i>=(b);i--)
#pragma GCC optimize(3,"Ofast","inline")
#define min(x,y) ((x)>(y)?(y):(x))
#define max(x,y) ((x)<(y)?(y):(x))
#define MP(x,y) make_pair((x),(y))
#define FOR(i,v) for(auto&(i):(v))
#include <bits/stdc++.h>
#define lowbit(x) (x&-x)
#define RE register int
#define INF 0x3f3f3f3f
#define EPS 0.00000001
#define Pi acos(-1.0)
#define nd second
#define st first

using namespace std;
typedef unsigned long long ull;
typedef pair<double,double> PDD;
typedef pair<double,int> PDI;
typedef pair<int,int> PII;
const int mo = 998244353;
const int mod = 1e9 + 7;
const int N = 1e6 + 10;
const int M = 1e4 + 10;
typedef long long ll;
const ll inf = 1e18;

template <class T> inline void read(T &x);
template <class T> inline int write(T x);
template <class T> inline void wri(T x);

// d:总长, n:跑道数, r:半径, s:直道长, w:跑道宽度, f:终点x坐标
double d, n, r, s, w, f, l1, l2;

PDD first_lane() {
    double tot = s * 2 + 2 * Pi * (r + l1); // 总长
    double D = d - int(d / tot) * tot;
    int mark;
    if (D <= f + s / 2) mark = 1;
    else if (D <= f + s / 2 + Pi * (r + l1)) mark = 2;
    else if (D <= f + s / 2 + Pi * (r + l1) + s) mark = 3;
    else if (D <= f + s / 2 + 2 * Pi * (r + l1) + s) mark = 4;
    else mark = 5;
    double x, y;
    if (mark == 1) {
        x = f - D;
        y = -r;
    }
    if (mark == 3) {
        D -= f + s / 2;
        D -= Pi * (r + l1);
        x = D - s / 2;
        y = r;
    }
    if (mark == 2) {
        D -= f + s / 2;
        double alpha = D / (r + l1);
        x = -s / 2 - r * sin(alpha);
        y = -r * cos(alpha);
    }
    if (mark == 4) {
        D -= f + s * 3 / 2;
        D -= Pi * (r + l1);
        double alpha = D / (r + l1);
        x = s / 2 + r * sin(alpha);
        y = r * cos(alpha);
    }
    if (mark == 5) {
        D -= f + s * 3 / 2;
        D -= 2 * Pi * (r + l1);
        x = s / 2 - D;
        y = -r;
    }
    return MP(x, y);
}

PDD other_lane(int id) {
    double R = r + (id - 1) * w;
    double tot = s * 2 + 2 * Pi * (R + l2); // 总长
    double D = d - int(d / tot) * tot;
    int mark;
    if (D <= f + s / 2) mark = 1;
    else if (D <= f + s / 2 + Pi * (R + l2)) mark = 2;
    else if (D <= f + s / 2 + Pi * (R + l2) + s) mark = 3;
    else if (D <= f + s / 2 + 2 * Pi * (R + l2) + s) mark = 4;
    else mark = 5;
    double x, y;
    if (mark == 1) {
        x = f - D;
        y = -R;

    }
    if (mark == 3) {
        D -= f + s / 2;
        D -= Pi * (R + l2);
        x = D - s / 2;
        y = R;
    }
    if (mark == 2) {
        D -= f + s / 2;
        double alpha = D / (R + l2);
        x = -s / 2 - R * sin(alpha);
        y = -R * cos(alpha);
    }
    if (mark == 4) {
        D -= f + s * 3 / 2;
        D -= Pi * (R + l2);
        double alpha = D / (R + l2);
        x = s / 2 + R * sin(alpha);
        y = R * cos(alpha);
    }
    if (mark == 5) {
        D -= f + s * 3 / 2;
        D -= 2 * Pi * (R + l2);
        x = s / 2 - D;
        y = -R;
    }
    return MP(x, y);
}

int main() {
#ifdef ONLINE_JUDGE
#else // LOCAL_TESTING
    freopen("test.txt", "r", stdin);
#endif // ONLINE_JUDGE
    cin >> n >> r >> s >> w >> f >> l1 >> l2;
    while (cin >> d) {
        printf("%.3lf ", d);
        for (RE i = 1; i <= n; i++) {
            if (i == 1) {
                PDD ans = first_lane();
                printf("%.4lf %.4lf ", ans.st, ans.nd);
            }
            else {
                PDD ans = other_lane(i);
                printf("%.4lf %.4lf ", ans.st, ans.nd);
            }
        } puts("");
    }
    return 0;
}

template <class T> inline void read(T &x) {
    x=0; int f=1;
    char c=getchar();
    while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
    while(isdigit(c))x=(x<<1)+(x<<3)+(c^48),c=getchar();
    x *= f; return;
}
template <class T> inline void wri(T x) {
    if(x<0)putchar(45),x=-x;
    if(x>9)wri(x/10);
    putchar(x%10+48);
}
template <class T> inline int write(T x) {
    wri(x); puts(""); return 1;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值