主なアイデア:進完全なバイナリツリーは、あなたが2つの数の最も近い共通の祖先(LCA)を見つけてみましょう。
アイデア:まず、バイナリの性質を理解しましょう。
ルートは1から始まるため、少し醜いです。xである点がある場合、その左の子は2 ∗ xです。 2 * x2∗x、そして彼の子供は2 ∗ x + 1 2 * x + 12∗バツ+1.次に、バイナリと組み合わせると、左のサブツリーが次のビット0の場合は1ビット左にシフトし、それ以外の場合は1になります。したがって、ポイントのサブツリーを左にシフトする必要があることがわかります。 2進数です(2進数)の接頭辞は最も近い共通の祖先(LCA)であり、2進数と16進数の関係は、16進数を4桁の2進数に変換できることです。次に、最初に16進数を2に変換できます。次に、2進法を16進法に変換します。接頭辞0を付けないように注意してください。最後に、最後の4桁が失われないように、最初に追加する必要があります。最後に、接頭辞0を削除します。
#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
typedef unsigned long long ull;
const int inf = 0x3f3f3f3f;
const int maxn = 2e5 +7 ;
const ll mod = 1e9 + 7;
#define mst(x, a) memset( x,a,sizeof(x) )
#define rep(i, a, b) for(int i=(a);i<=(b);++i)
#define dep(i, a, b) for(int i=(a);i>=(b);--i)
inline ll read() {
ll x = 0;
bool f = 0;
char ch = getchar();
while (ch < '0' || '9' < ch)
f |= ch == '-', ch = getchar();
while ('0' <= ch && ch <= '9')
x = x * 10 + ch - '0', ch = getchar();
return f ? -x : x;
}
void out(ll x) {
int stackk[20];
if (x < 0) {
putchar('-');
x = -x;
}
if (!x) {
putchar('0');
return;
}
int top = 0;
while (x)
stackk[++top] = x % 10, x /= 10;
while (top)
putchar(stackk[top--] + '0');
}
ll qpow(ll a,ll b) {
ll ans=1;
while(b) {
if(b&1) ans=ans*a%mod;
a=a*a%mod;
b>>=1;
}
return ans;
}
string str,s;
map<char,string >mp;
map<string,char >mpp;
int main() {
int _=read();
mp['0']="0000";
mp['1']="0001";
mp['2']="0010";
mp['3']="0011";
mp['4']="0100";
mp['5']="0101";
mp['6']="0110";
mp['7']="0111";
mp['8']="1000";
mp['9']="1001";
mp['a']="1010";
mp['b']="1011";
mp['c']="1100";
mp['d']="1101";
mp['e']="1110";
mp['f']="1111";
mpp["0000"]='0';
mpp["0001"]='1';
mpp["0010"]='2';
mpp["0011"]='3';
mpp["0100"]='4';
mpp["0101"]='5';
mpp["0110"]='6';
mpp["0111"]='7';
mpp["1000"]='8';
mpp["1001"]='9';
mpp["1010"]='a';
mpp["1011"]='b';
mpp["1100"]='c';
mpp["1101"]='d';
mpp["1110"]='e';
mpp["1111"]='f';
ll T=0;
while(_--) {
cin>>str>>s;
string ans_str,ans_s;
string ans,ans1;
for(int i=0; i<str.size(); i++) {
ans_str+=mp[str[i]];
}
for(int i=0; i<s.size(); i++) {
ans_s+=mp[s[i]];
}
for(int i=0; i<ans_str.size(); i++) {
if(ans_str[i]=='0') {
continue;
} else {
ans_str=ans_str.substr(i,ans_str.size()-i);
break;
}
}
for(int i=0; i<ans_s.size(); i++) {
if(ans_s[i]=='0') {
continue;
} else {
ans_s=ans_s.substr(i,ans_s.size()-i);
break;
}
}
///cout<<ans_str<<endl;
///cout<<ans_s<<endl;
for(int i=0; i<min(ans_str.size(),ans_s.size()); i++) {
if(ans_str[i]==ans_s[i]) {
ans=ans+ans_str[i];
} else break;
}
ans="00000"+ans;///这个地方出过一次锅
for(int i=ans.size()-1; i>=3; i-=4) {
string q=ans.substr(i-3,4);
ans1=mpp[q]+ans1;
}
for(int i=0; i<ans1.size(); i++) {
if(ans1[i]=='0') {
continue;
} else {
ans1=ans1.substr(i,ans1.size()-i);
break;
}
}
printf("Case #%lld: ",++T);
cout<<ans1<<endl<<endl;
}
return 0;
}