CF1728C Digital Logarithm 题解
题目链接:CF1728C Digital Logarithm
题意:
我们定义 $f(x)$ 表示取出 $x$ 在十进制下的位数。( 如 $f(114514) = 6, \; f(998244353) = 9$ )。形式化讲,就是 $f(x) = \lfloor \log_{10} x \rfloor$
给定两个数组 $a$ 和 $b$,求执行若干次以下操作后使得 $a$ 和 $b$ 排序后相等的最小操作次数。
操作方法如下:
- 选择一个下标 $i$,将 $a_i$ 赋值为 $f(a_i)$ 或者将 $b_i$ 赋值为 $f(b_i)$。
输入格式:
第一行一个整数 $T \; (1 \le T \le 10^4)$ 表示测试样例组数。
对于每组测试样例,第一行为一个整数 $n \; (1 \le n \le 2 \cdot 10^5)$ 表示数组长度。
接下来的两行分别有 $n$ 个整数,表示数组 $a$ 和 $b \; (1 \le a_i,b_i < 10^9)$。
数据保证 $\sum n \le 2 \times 10^5$
输出格式:
对于每组测试样例,输出包含一行一个整数,表示最小操作次数。
记录一下这道在最后几秒交上去Accepted了然后又被Hacked的题。
可以发现这个数据范围下,再大的数至多两次就削成 $1$ 了。
根据贪心的思想,我们每次取出当前 $a$ 数组和 $b$ 数组各自的最大值
如果他们相同,就把他们同时扔掉。否则把较大的那个削一下。
说实话这东西看上去很对很简单,但是我就是没想到。。
然后我当时搞得可能常数太大了寄了。因为排序了好几遍。
时间复杂度 $O(2\sum n\log\sum n)$
代码:
#include <bits/stdc++.h>
using namespace std;
#define int long long
#define INF 0x3f3f3f3f3f3f3f3f
#define N ((int)())
int n;
priority_queue<int> a,b;
int f(int x){return to_string(x).size();}
void clear()
{
while(!a.empty()) a.pop();
while(!b.empty()) b.pop();
}
void solve()
{
clear(); cin >> n;
for(int i=1,x; i<=n; i++) cin >> x, a.push(x);
for(int i=1,x; i<=n; i++) cin >> x, b.push(x);
int ans=0;
while(!a.empty())
{
int x=a.top(), y=b.top();
if(x > y)
{
a.pop(); a.push(f(x)); ++ans;
}else if(x < y)
{
b.pop(); b.push(f(y)); ++ans;
}else a.pop(),b.pop();
}
cout << ans << '\n';
}
signed main()
{
ios::sync_with_stdio(0);
cin.tie(0);cout.tie(0);
// freopen("check.in","r",stdin);
// freopen("check.out","w",stdout);
int _Q=1; cin >> _Q;
while(_Q--)solve();
return 0;
}