2022ICPC区域赛济南站
补题链接QOJ:The 2022 ICPC Asia Jinan Regional Contest - Dashboard - Contest - QOJ.ac
K. Stack Sort
思路:考虑 a 需要比 a+1 先出栈,所以如果读到 a,发现 a+1 还没被记录则需要多建一个栈。
void solve()
{
int n;
cin >> n;
int num = 0;
for (int i = 0; i < n; i++)
{
cin >> a[i];
if (!vis[a[i] + 1])
{
num++;
}
vis[a[i]] = 1;
}
cout << num << '\n';
for (int i = 1; i <= n; i++)
{
vis[i] = 0;
}
}
M. Best Carry Player
思路:与顺序无关,只需要模拟过程进位几次。需要注意连续进位。
void solve()
{
int n;
cin >> n;
int ans = 0;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
}
auto add = [&](auto x, auto y)
{
int sum = x + y;
auto n1 = 0, n2 = 0;
while (x != 0 || y != 0)
{
n1 += x % 10; //记录上一位是否有进位
x /= 10;
n2 = y % 10;
y /= 10;
ans += (n1 + n2 >= 10) ? 1 : 0;
n1 = (n1 + n2 >= 10) ? 1 : 0;
// cerr<<x<<' '<<y<<' '<<ans<<' '<<n1<<' '<<n2<<'\n';
}
return sum;
};
int st = a[1];
for (int i = 2; i <= n; i++)
{
st = add(st, a[i]);
}
cout << ans << '\n';
}
E. Identical Parity
思路:先特判,k=1时除了n=1都不合法;k为偶数一定合法,直接奇偶相间输出;
所以只需要分析k为奇数的情况。
题目相当于在i i+k i+2k·····等位置上放置奇偶性相同的数,共有k个完整组。
首先我们可以根据n的大小计算1-n的奇数和偶数个数;
然后因为k是奇数,对于放奇数的位置,我们分出k/2+1组;偶数则为k/2组。
然后计算剩余的奇偶数是否满足放置条件即可。
[2022icpc济南 ADEKM - 知乎](https://zhuanlan.zhihu.com/p/590527069) 讲的很清晰。
void solve()
{
cin >> n >> k;
if (n == 1)
{
yes;
re;
}
if (k == 1)
{
no;
re;
}
if (k % 2 == 0)
{
yes;
re;
}
int odd = (n + 1) / 2, even = n / 2; // 计算n中奇偶数个数
int ke = k / 2, ko = k / 2 + 1; // 因为k是奇数,我们令偶数占小的一半
int zu = n / k; // 每组分配的个数,因为每一组填入的奇偶性相同
int yu = n % k; // 分配后剩下的数
int yuodd = odd - ko * zu, yueven = even - ke * zu;
//奇数余数=奇数总数-k/2+1个奇数组*每组填入个数,偶数余数同理
if (yuodd >= 0 && yueven >= 0 && yueven + yuodd == yu)
{
if (yuodd <= ko && yueven <= ke)//确保余数要小于对应组数
{
yes;
re;
}
no;
re;
}
no;
re;
}
A. Tower
思路:一个trick:给定一个数组,通过 ±1 使所有数相同,最小操作是变成中位数。
现在多了一个/2操作,不确定中位数会是哪个,但能保证结果在这些数之间,所以暴力枚举求最小值。
比如 如果设目标位x,起始位a,让a->x。
- a<x 只能通过+1到达
- a>x 我们可以考虑先/后±或者先±后/,可以证明前者一定不劣于后者。
void solve()
{
cin >> n >> k;
set<int> st;
rep(1, i, n)
{
cin >> a[i];
x = a[i];
while (x)
{
st.insert(x);
x /= 2;
}
}
minn = 1e18;
for (auto i : st)
{
rep(1, j, n)
{
if (a[j] <= i)
{
b[j] = i - a[j];
}
else
{
num = 0;
x = a[j];
while (x / 2 >= i)
{
x /= 2;
num++;
}
b[j] = min(num + (x - i), num + 1 + (i - x / 2)); //分别考虑不除以和除以2
}
}
ans = 0;
sort(b + 1, b + 1 + n);
rep(1, i, n - k)
{
ans += b[i];
}
minn = min(ans, minn);
}
cout << minn;
}

浙公网安备 33010602011771号