• 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
    ", a[(k - 1) % s + 1]);
    		else if(k <= t) printf("%.8Lf
    ", a[k]);
    		else {
    			k -= t, s -= t;
    			printf("%.8Lf
    ", a[(k - 1) % s + 1 + t]);
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    leetcode 122. Best Time to Buy and Sell Stock II
    leetcode 121. Best Time to Buy and Sell Stock
    python 集合(set)和字典(dictionary)的用法解析
    leetcode 53. Maximum Subarray
    leetcode 202. Happy Number
    leetcode 136.Single Number
    leetcode 703. Kth Largest Element in a Stream & c++ priority_queue & minHeap/maxHeap
    [leetcode]1379. Find a Corresponding Node of a Binary Tree in a Clone of That Tree
    正则表达式
    十种排序算法
  • 原文地址:https://www.cnblogs.com/LZA119/p/14279503.html
Copyright © 2020-2023  润新知