Newcoder 110 F.Alice收集玩偶(计算几何)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/V5ZSQ/article/details/83111400

Description

A l i c e Alice 是个小女孩,最近经常睡得很晚起得也很晚。 她的母亲希望她能戒掉这个坏习惯,所以对 A l i c e Alice 说:“如果你早睡一天,我会给你一张粉红色的贴纸。 如果你早起一天,我会给你一张橙色的贴纸。"

A l i c e Alice 长大后,她成为了一个早睡早起的好女孩。 她已经收集了 A A 张粉红色的贴纸和 B B 张橙色的贴纸。 但她不再喜欢贴纸。 所以她再也不会收集贴纸了。 有一天,她向妈妈抱怨她不喜欢贴纸了。 她的母亲对她说:“那么现在,你可以用 x 1 x_1 张粉红色贴纸和 y 1 y_1 张橙色贴纸来换一只小猫玩偶,或者用 x 2 x_2 张粉红色贴纸和 y 2 y_2 张橙色贴纸来换一只小狗玩偶。

A l i c e Alice 听了妈妈的话开心了起来,她想收集尽可能多的玩偶。

现在,请您计算 A l i c e Alice 可以获得的玩偶数量最多是多少(玩偶都是完整的,没有半只玩偶这类的东西)。

Input

输入的第一行将包含一个整数 T T ,表示您应该处理的查询数量。

对于每个查询,给出一行包含六个整数 A B x 1 y 1 x 2 y 2 A,B,x_1,y_1,x_2,y_2 ,表示上述语句中的数值。

( 1 T 1 0 5 , 1 A , B , x 1 , y 1 , x 2 , y 2 2 1 0 9 ) (1\le T\le 10^5,1\le A,B,x_1,y_1,x_2,y_2\le 2\cdot 10^9)

Output

对于每个查询,输出一行表示答案的整数。

Sample Input

4
10 10 2 3 3 2
10 14 2 3 3 2
10 15 2 3 3 2
1000000000 999999999 1 4 10000 3

Sample Output

4
4
5
250018751

Solution

不妨设 x 1 x 2 x_1\le x_2 ,若 x 1 = x 2 x_1=x_2 则不妨设 y 1 y 2 y_1\le y_2

y 1 y 2 y_1\le y_2 显然全买第一种即可,否则假设买 t t 个第一种,那么最多可以买的个数为
t + m i n ( A x 1 t x 2 , B y 1 t y 2 ) t+min(\frac{A-x_1\cdot t}{x_2},\frac{B-y_1\cdot t}{y_2})
也即为 y = x 2 x 1 x 2 t + A x 2 y=\frac{x_2-x_1}{x_2}\cdot t+\frac{A}{x_2} y = y 2 y 1 y 2 t + B y 2 y=\frac{y_2-y_1}{y_2}\cdot t+\frac{B}{y_2} 两条直线取较小值后的最大值,显然第一条直线单增,第二条直线单减,两者取最小值应为一个先增后减的折线,求出两条直线交点对应的 t t 值,判断其是否合法,如果合法则该 t t 值即为所求,否则取两个端点值比较一下选出较优值即为答案,注意到这里的 t t 值需要是整数,而两条直线交点对应的横坐标不一定是整数,故也需取交点横坐标左右两个 t t 值进行比较

Code

#include<cstdio>
#include<algorithm>
using namespace std;
typedef long long ll;
#define y1 yy1
int T,A,B,x1,x2,y1,y2;
int get(int t)
{
	if(A/x1<t||B/y1<t)return 0;
	return t+min((A-x1*t)/x2,(B-y1*t)/y2);
}
int main()
{
	scanf("%d",&T);
	while(T--)
	{
		scanf("%d%d%d%d%d%d",&A,&B,&x1,&y1,&x2,&y2);
		int ans=0;
		if(x1>x2)swap(x1,x2),swap(y1,y2);
		if(x1==x2&&y1>y2)swap(y1,y2);
		if(y1<=y2)printf("%d\n",get(min(A/x1,B/y1)));
		else
		{
			ll temp=(1ll*x2*B-1ll*y2*A)/(1ll*x2*y1-1ll*x1*y2);
			if(temp<0||temp>min(A/x1,B/y1))printf("%d\n",max(get(0),get(min(A/x1,B/y1))));
			else printf("%d\n",max(get(temp),get(temp+1)));	
		}
	} 
	return 0;
}

猜你喜欢

转载自blog.csdn.net/V5ZSQ/article/details/83111400
110