CF1523C Compression and Expansion
前言
多测不清零,亲人两行泪。
题意
对于一个空的数字串,有两种操作:
- 删除末尾的 \(n\) 个 \((n \ge 0)\) 元素,并将修改后数字串的最后一个元素加一;
- 在数字串末尾添加一个数字 \(1\)。
输入 \(n\) 个元素,表示第 \(n\) 次操作后数字串末尾的元素。
思路
首先考虑较为简单的操作二。
很明显,当添加的元素 \(a = 1\) 时,我们可以直接使用操作二。当然,这也是操作二唯一的用途。
再考虑操作一。
当数字串中的数 \(i\) 满足什么条件时,可以进行操作呢?思考一下可以得出,当 \(i = a - 1\) 时,可以对其进行操作一。
那么现在思路就很明朗了,首先判断 \(a\) 是否为 \(1\),如果是,直接操作一;如果不是,枚举数字串直到找一个元素 \(i = a - 1\),进行操作二。(这里可以默认题目给出的数据一定有解)。
在枚举时注意一个细节:倒序枚举。这样可以在数字串中保留尽可能多的元素,方便以后的运算。
最后考虑输出的细节,先不要输出数字串的末尾元素,这样方便按照格式输出。
代码
#include <bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int n, a, rcnt = 0;
int rem[N];
void init() {
memset(rem, 0, sizeof(rem));
rcnt = 0;
}
int main() {
int T;
scanf("%d", &T);
while (T--) {
init();
scanf("%d", &n);
for (int i = 1; i <= n; i++) {
scanf("%d", &a);
if (a == 1) {
rcnt++;
rem[rcnt] = 1;
} else {
for (int j = rcnt; j >= 1; j--) {
if (rem[j] != a - 1) rcnt--;
else {
rem[j] = a;
rcnt = j;
break;
}
}
}
for (int j = 1; j < rcnt; j++) printf("%d.", rem[j]);
printf("%d\n", rem[rcnt]);
}
}
return 0;
}
多测不清零,亲人两行泪。
Blog by cloud_eve is licensed under CC BY-NC-SA 4.0