http://acm.hdu.edu.cn/showproblem.php?pid=6726
考虑A,B操作,可以发现每次A操作(a,2*(b-a)+a)->(a,4*(b-a)+a)->(a,8*(b-a)+a),B操作也是类似。
可以看见每次a,b之间的长度增长是原始长度的len=abs(b-a)的二的幂次倍
而且a,b移动的长度也原始长度len的2的幂次倍
于是只要(a,b)能移动到c,d,那么答案是唯一的,不存在字典序最小的问题。
注意一个问题,移动的时候要判断(b-d)%len==0,因为每次移动len的2的幂次倍。
因为是len的2的幂次倍,所以b-d只要是len的倍数,都可以得到答案。
#include<bits/stdc++.h>
#define maxl 100010
using namespace std;
typedef pair<long long,long long> p;
long long a,b,c,d,cnt;
bool flag;
int ans[maxl];
inline void prework()
{
scanf("%lld%lld%lld%lld",&a,&b,&c,&d);
}
inline bool jug(long long x)
{
cnt=0;
long long len=abs(c-d);
while(x<=len)
{
if(x==len)
return true;
x=x*2;cnt++;
}
return false;
}
inline void mainwork()
{
flag=false;long long x,len;
ans[0]=0;
if(a==b)
{
if(a!=c || b!=d)
{
flag=false;
return;
}
else
{
flag=true;
ans[0]=0;
}
}
else if(a<b)
{
x=b-a;
if(c>a || d<b || !jug(x))
{
flag=false;
return;
}
if((d-b)%x!=0)
{
flag=false;
return;
}
flag=true;
long long num=(d-b)/x;
for(int i=1;i<=cnt;i++)
{
if(num&1ll)
ans[++ans[0]]=1;
else
ans[++ans[0]]=2;
num>>=1ll;
}
}
else if(a>b)
{
x=a-b;
if(b<d || a>c || !jug(x))
{
flag=false;
return;
}
if((b-d)%x!=0)
{
flag=false;
return;
}
flag=true;
long long num=(b-d)/x;
for(int i=1;i<=cnt;i++)
{
if(num&1ll)
ans[++ans[0]]=1;
else
ans[++ans[0]]=2;
num>>=1ll;
}
}
}
inline void print()
{
if(flag)
{
puts("Yes");
for(int i=1;i<=ans[0];i++)
printf("%c",'A'+ans[i]-1);
puts("");
}
else
puts("No");
}
int main()
{
int t;
scanf("%d",&t);
for(int i=1;i<=t;i++)
{
prework();
mainwork();
print();
}
return 0;
}