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

Description

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

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

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

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

Input

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

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

( 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) (1T105,1A,B,x1,y1,x2,y22109)

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 x1x2,若 x 1 = x 2 x_1=x_2 x1=x2则不妨设 y 1 ≤ y 2 y_1\le y_2 y1y2

y 1 ≤ y 2 y_1\le y_2 y1y2显然全买第一种即可,否则假设买 t 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}) t+min(x2Ax1t,y2By1t)
也即为 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=x2x2x1t+x2A 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} y=y2y2y1t+y2B两条直线取较小值后的最大值,显然第一条直线单增,第二条直线单减,两者取最小值应为一个先增后减的折线,求出两条直线交点对应的 t t t值,判断其是否合法,如果合法则该 t 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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值