2020“图灵杯”趣味网络邀请赛 A. 相遇(分类讨论+数学计算)
2020“图灵杯”趣味网络邀请赛 A. 相遇
题解
- 路径总长 100 100 100,速度也小于等于 10 10 10,而 k k k却特别大,想到可以依次找出所有相遇位置,当出现循环则退出,可以证明这样复杂度是可以过的。
- 如何快速的找到每次相遇的位置呢?
- 直接分类讨论,相向时可以计算相遇,追及且能追上时可以计算相遇,其余情况则让两个人往他们当前方向的端点跑,设两人到端点时间分别为 t x , t y tx,ty tx,ty,则计算时间 m i n ( t x , t y ) min(tx,ty) min(tx,ty)后的位置(因为这样做计算简便)。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define ll long long
#define ld long double
#define N 100010
ld a[N];
ll read() {
ll s = 0;
char x = getchar();
while(x < '0' || x > '9') x = getchar();
while(x >= '0' && x <= '9') s = s * 10 + x - 48, x = getchar();
return s;
}
int main() {
int tn = read();
while(tn--) {
ll k = read();
ld v1 = read(), v2 = read(), X = read();
ld x = 0, ox = 1, y = X, oy = -1;
int s = 0, t = 0, i;
while(s == 0 || x != 0 || y != X || oy != -1) {
if(ox == 1 && oy == -1 && x < y) {
x = y = x + (y - x) / (v1 + v2) * v1;
ox = -1, oy = 1;
a[++s] = x;
for(i = 1; i < s; i++) if(a[i] == x) {
t = i;
break;
}
if(t) break;
}
else if(ox == -1 && oy == 1 && y < x) {
x = y = y + (x - y) / (v1 + v2) * v2;
ox = 1, oy = -1;
a[++s] = x;
for(i = 1; i < s; i++) if(a[i] == x) {
t = i;
break;
}
if(t) break;
}
else if(v1 >= v2 && ox == oy && ox == 1 && x < y && x + (y - x) / (v1 - v2) * v1 <= 100) {
x = y = x + (y - x) / (v1 - v2) * v1, ox = -1;
a[++s] = x;
for(i = 1; i < s; i++) if(a[i] == x) {
t = i;
break;
}
if(t) break;
}
else if(v1 >= v2 && ox == oy && ox == -1 && x > y && x - (x - y) / (v1 - v2) - v1 >= 0) {
x = y = x - (x - y) / (v1 - v2) * v1, ox = 1;
a[++s] = x;
for(i = 1; i < s; i++) if(a[i] == x) {
t = i;
break;
}
if(t) break;
}
else if(v1 <= v2 && ox == oy && oy == 1 && y < x && y + (x - y) / (v2 - v1) * v2 <= 100) {
x = y = y + (x - y) / (v2 - v1) * v2, oy = -1;
a[++s] = x;
for(i = 1; i < s; i++) if(a[i] == x) {
t = i;
break;
}
if(t) break;
}
else if(v1 <= v2 && ox == oy && oy == -1 && y > x && y - (y - x) / (v2 - v1) * v2 >= 0) {
x = y = y - (y - x) / (v2 - v1) * v2, oy = 1;
a[++s] = x;
for(i = 1; i < s; i++) if(a[i] == x) {
t = i;
break;
}
if(t) break;
}
else if(ox == -1) {
ld tx = x / v1;
if(oy == -1) {
ld ty = y / v2;
if(tx <= ty) {
x = 0, y -= v2 * tx, ox = 1;
if(y == 0) oy = 1;
}
else {
y = 0, x -= v1 * ty, oy = 1;
if(x == 0) ox = 1;
}
}
else {
ld ty = (100.0 - y) / v2;
if(tx <= ty) {
x = 0, y += v2 * tx, ox = 1;
if(y == 100) oy = -1;
}
else {
y = 100, x -= v1 * ty, oy = -1;
if(x == 0) ox = 1;
}
}
}
else {
ld tx = (100.0 - x) / v1;
if(oy == -1) {
ld ty = y / v2;
if(tx <= ty) {
x = 100, y -= v2 * tx, ox = -1;
if(y == 0) oy = 1;
}
else {
y = 0, x += v1 * ty, oy = 1;
if(x == 100) ox = -1;
}
}
else {
ld ty = (100.0 - y) / v2;
if(tx <= ty) {
x = 100, y += tx * v2, ox = -1;
if(y == 100) oy = -1;
}
else {
y = 100, x += ty * v1, oy = -1;
if(x == 100) ox = -1;
}
}
}
}
if(!t) printf("%.8Lf\n", a[(k - 1) % s + 1]);
else if(k <= t) printf("%.8Lf\n", a[k]);
else {
k -= t, s -= t;
printf("%.8Lf\n", a[(k - 1) % s + 1 + t]);
}
}
return 0;
}
哈哈哈哈哈哈哈哈哈哈

浙公网安备 33010602011771号