CF1523C Compression and Expansion

发布时间 2024-01-07 16:28:29作者: cloud_eve

前言

多测不清零,亲人两行泪。

题意

对于一个空的数字串,有两种操作:

  1. 删除末尾的 \(n\)\((n \ge 0)\) 元素,并将修改后数字串的最后一个元素加一;
  2. 在数字串末尾添加一个数字 \(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;
}

多测不清零,亲人两行泪