2018焦作 Gym - 102028B - Ultraman vs. Aodzilla and Bodzilla【贪心模拟】

Six months ago our hero, formerly known as Huriyyah, was beating all monsters in the land. Now he changed his name to Ultraman and left his beloved land. He is ready to take on a new challenge.

In a remote land, local citizens are suffering from the harassment of two powerful and horrible monsters: Aodzilla and Bodzilla. They eat small children who go out alone and even kill innocent persons. The apprehension of being attacked has overwhelmed people for several decades.

For the good of these unfortunate citizens, Ultraman sets out for the forest which is the main lair of Aodzilla and Bodzilla. In the forest, he faces these two fierce and cruel monsters and fights with them. The health points of Aodzilla and Bodzilla are HPAHPA and HPBHPB respectively, and their attack values are ATKAATKA and ATKBATKBrespectively.

They fight in a cave through turn-based battles. During each second, the Ultraman will be attacked by monsters at first, and the damage is the sum of attack values of all alive monsters. Then he will select exactly one monster which is still alive and attack it. The selected monster will suffer a damage of value ii (i.e. its health point will be decreased by ii) where ii represents that Ultraman has launched iiattacks in total, from the beginning to the present, to these two monsters (and the current attack is the ii-th one). That is to say, during the 11-st second, one of these two monsters will be under an attack of damage 11, during the 22-nd second, one of them, if alive, will be under an attack of damage 22, during the 33-rd second, one of them, if alive, will be under an attack of damage 33, and so on. If at some time, the health point of a monster is less than or equal to zero, it will die immediately. The Ultraman will win if both monsters have been killed.

Now, you are asked to develop a strategy to minimize the total damage Ultraman should suffer before he wins the battle. A strategy can be described as a string whose length is the total time that the battle will last. The ii-th character in the string is 'A', if the Ultraman chooses to attack Aodzilla during the ii-th second; otherwise, the ii-th character is 'B', which means Bodzilla will be the target during that second. You are also asked to find the optimal strategy whose string description is the smallest in lexicographical order among all possible optimal strategies.

For two distinct strings ss and tt, if one string is a prefix of the other, then the one with a shorter length is smaller in lexicographical order. In other cases, ss is smaller than tt in lexicographical order if the first character of ss is smaller than the first character of tt, or in case they are equivalent, the second character of ssis smaller than the second character of tt, etc. The case tt is smaller than ss in lexicographical order is defined similarly as the former case.

Input

The input contains several test cases, and the first line contains a positive integer TT indicating the number of test cases which is up to 105105.

For each test case, the only one line contains four integers HPAHPA, HPBHPB, ATKAATKA and ATKBATKB, where 1≤HPA,HPB,ATKA,ATKB≤1091≤HPA,HPB,ATKA,ATKB≤109.

We guarantee that there are at most 100100 test cases with max{HPA,HPB}>103max{HPA,HPB}>103.

Output

For each test case, output a line containing an integer indicating the minimal total damage Ultraman should suffer, and a string describing the optimal strategy such that the string description is the smallest in lexicographical order among all possible optimal strategies. You should output exactly one whitespace between the number and the string.

Example

Input

2
5 15 5 25
5 15 25 5

Output

155 BBBBBA
105 AAABBB

 

 

分析:要使收到的伤害最小,那么一定要先打死其中一个。分别考虑先打死A和B的情况。

首先处理一个前缀和的数组Num[i]表示1到i时刻的伤害总和。

打死两个所需的最小时间 last = lower_bound(num+1,num+100004,hpa+hpb)-num

A:最快打死A的时刻:time = lower_bound(num+1,num+100004,hpa)-num

(1)从time+1到last时刻的伤害足够打死B,那么前time个是A,后面的是B

(2)从time+1到last时刻的伤害不够打死B,那么需要在前面插入B,可以证明从time+1到last的伤害和hpb的差值一定小于time,那么保证字典序最小,就在第  num[time]-hpa 处插入B就可以了。

B:最快打死B的时刻:time = lower_bound(num+1,num+100004,hpb)-num

依然分两种情况。

在能打死B的情况下,我们从第一个开始将A插入,但是可能出现最后打不死的A情况,这时我们需要把插入的A往后移。

(1)在上述情况下,定义left为ha - num[last]-num[time],在1到time时刻,如果left-i>i(保证后面可以将left减掉)或者left==i(一定要把left减完才能保证A可以打死)插入A且left-=i,否则插入B。剩下的时刻全部都是A。

(2)直接插入A的前缀,中间是B,剩下是A即可。

 

最后判断一下大小输出即可。

#include<bits/stdc++.h>

namespace fastIO {
#define BUF_SIZE 100000
    bool IOerror = 0;inline char nc() { static char buf[BUF_SIZE], *p1 = buf + BUF_SIZE, *pend = buf + BUF_SIZE;if (p1 == pend) { p1 = buf;pend = buf + fread(buf, 1, BUF_SIZE, stdin);if (pend == p1) { IOerror = 1;return -1; }}return *p1++; }
    inline bool blank(char ch) { return ch == ' ' || ch == '\n' || ch == '\r' || ch == '\t'; }
    inline void read(int &x) {char ch;while (blank(ch = nc()));if (IOerror) return;for (x = ch - '0'; (ch = nc()) >= '0' && ch <= '9'; x = x * 10 + ch - '0'); }
    inline void Out(int a) { if (a < 0) { putchar('-');a = -a; }if (a >= 10) { Out(a / 10); }putchar(a % 10 + '0'); }
#undef BUF_SIZE
};
using namespace fastIO;
using namespace std;
long long num[100004];
int main()
{
    for (long long i = 1; i < 100004; ++i) {
        num[i]=num[i-1]+1LL*i;
    }
    int T;  scanf("%d", &T);
    while(T--)
    {
        long long ha,hb,ta,tb;
        long long resa=0,resb=0;
        scanf("%lld%lld%lld%lld",&ha,&hb,&ta,&tb);
        string ansa,ansb;

        long long pos = lower_bound(num+1,num+100004,ha)-num;//A
        long long last = lower_bound(num+1,num+100004,ha+hb)-num;///A+B
        long long duo=num[pos]-ha;
        long long tsa = 1LL*last*tb+1LL*pos*ta;
        if(num[last]-num[pos]>=hb){
            for (long long i = 1; i <= pos; ++i) {
                ansa+='A';
            }
        } else {
            for (long long i = 1; i <= pos; ++i) {
                if(i!=duo)ansa+='A';
                else ansa+='B';
            }
        }
        for (long long i = pos+1; i <= last; ++i) {
            ansa+='B';
        }

        pos = lower_bound(num+1,num+100004,hb)-num;///B
        duo = num[pos]-hb;
        long long pos2 = upper_bound(num+1,num+100004,duo)-num-1;
        long long hou = num[last]-num[pos];
        long long tsb = 1LL*last*ta + 1LL*pos*tb;
        if(hou+num[pos2]>=ha)
        {
            for (long long i = 1; i <= pos2; ++i) {
                ansb+='A';
            }
            for (long long i = pos2+1; i <= pos; ++i) {
                ansb+='B';
            }
            for (long long i = pos+1; i <= last; ++i) {
                ansb+='A';
            }
        } else {
            long long left = ha - hou ;
            for (long long i = 1; i <= pos; ++i) {
                if(left-i>i||left==i){
                    left-=i;
                    ansb+='A';
                }
                else ansb+='B';
                
            }
            for (long long i = pos+1; i <= last; ++i) {
                ansb+='A';
            }
        }
        if(tsb<tsa)
            printf("%lld ",tsb);cout<<ansb<<endl;
        else if(tsb>tsa)
            printf("%lld ",tsa);cout<<ansa<<endl;
        else if(ansa<ansb)
            printf("%lld ",tsa);cout<<ansa<<endl;
        else 
            printf("%lld ",tsb);cout<<ansb<<endl;
    }
}
/*
 * 836075520
 */

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值