题目意思:
给你两个数组,然后给你一个操作,问最少需要经过多少次操作才能使这两个数组相似(通过排序后数组相等)。
这个操作是:将任意一个数组的某个数组元素的值变成他的长度(size ).
思路:用两个map存储每个数组出现的次数,然后用两个优先队列存储这两个数组的元素,每次取对头,如果对头的(最大值)元素在另一个数组都有出现的话,那么直接出队然后map回退一下就可以了;如果只有一个元素在另一个数组有出现的话,那么另一个元素因为是最大值,那么他一定要经过操作才可能使两个数组相等,那么就把这个元素变成他的size,同时map的值改变一下,出栈;如果两个元素在另一个数组都没有值的话,直接无脑变size就好。最后输出的res就是最后的结果。从最大值开始不断判断,因为最大值如果存在就可以那么先退一定比后退优
/**
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████+
* ◥██◤ ◥██◤ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃ + + + +Code is far away from
* ┃ ┃ + bug with the animal protecting
* ┃ ┗━━━┓ 神兽保佑,代码无bug
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +
*/
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
#include <math.h>
#include <vector>
#include <queue>
#include <map>
#define sc_int(x) scanf("%d", &x)
#define sc_ll(x) scanf("%lld", &x)
#define pr_ll(x) printf("%lld", x)
#define pr_ll_n(x) printf("%lld\n", x)
#define pr_int_n(x) printf("%d\n", x)
#define ll long long
using namespace std;
typedef priority_queue<int> Queue;
Queue a, b;
map<int, int> a_q, b_q;
const int N = 1000000 + 100;
int n, m, h;
ll s[N];
int Size(int x)
{
int sum = 0;
while (x)
{
sum++;
x /= 10;
}
// cout<<sum<<endl;
return sum;
}
void change(Queue &a_q, map<int, int> &a, int x)
{
a[x]--;
a_q.push(Size(x));
a[Size(x)]++;
}
int main()
{
int t;
sc_int(t);
while (t--)
{
while (a.size())
a.pop();
while (b.size())
b.pop();
sc_int(n);
int x;
for (int i = 1; i <= n; i++)
{
cin >> x;
a.push(x);
a_q[x] += 1;
}
for (int i = 1; i <= n; i++)
{
cin >> x;
b.push(x);
b_q[x] += 1;
}
int res = 0;
while (a.size())
{
int aa = a.top(), bb = b.top();
if (a_q[bb] && b_q[aa])
{
a_q[aa]--;
b_q[bb]--;
a.pop(), b.pop();
continue;
}
if (!a_q[bb] && !b_q[aa])
{
if (aa > bb)
{
change(a, a_q, aa);
a.pop();
}
else
{
change(b, b_q, bb);
b.pop();
}
res++;
}
else if (!a_q[bb])
{
res++;
change(b, b_q, bb);
b.pop();
}
else if (!b_q[aa])
{
res++;
change(a, a_q, aa);
a.pop();
}
}
cout << res << endl;
}
return 0;
}