Problem A
有两条以(0,0)为端点,分别经过(a,b),(c,d)的射线,你要求出夹在两条射线
中间,且距离(0,0)最近的点(x,y)对于$100\%$的数据满足$1 \leq T \leq 10^6 , 0 \leq a,b,c,d \leq 10^9$
Solution :
每次删除一个下面那条线斜率下取整这块三角形,然后将y坐标下移,
每一次分治下去,最后一定会存在一个时刻$(1,1)$合法,此时回溯回去即可。
由于分治前后,线段的相对位置不变,不会存在新的点更优,所以最后生成的答案一定是最优的。
每次查询的复杂度大约是$O(n)$的。
具体可以看下面$a = 2,b = 7,c = 4,d = 10$的求值方法。
# include <bits/stdc++.h> # define int long long using namespace std; void work(int a,int b,int c,int d,int &x,int &y) { if (a<b&&c>d) { x=1,y=1; return; } if (a*d>b*c) work(c,d,a,b,x,y); else if (a>=b) work(b,a,d,c,y,x); else { int t=d/c; work(a,b-t*a,c,d-t*c,x,y); y+=t*x; } } main() { int T; scanf("%lld",&T); while (T--) { int a,b,c,d; scanf("%lld%lld%lld%lld",&a,&b,&c,&d); int x,y; if (a*d>b*c) swap(a,c),swap(b,d); work(a,b,c,d,x,y); printf("%lld %lld\n",x,y); } return 0; }