描述
题解
这个题很明显是找规律的问题,直接暴力肯定会超时……虽然我也是暴力也两发才反应过来……平时做题总是抱着侥幸心理,比赛时却总是胆小如鼠……
自己手解几组长一点的数据就可以发现,不管初始状态如何,最终都会变成连续的
0
和连续的
经过推算发现,最后的格式和这个子序列的长度的奇偶性有关,
如果是奇数,最后的格式要么全是
如果是偶数的话,最后的格式要么是一半
如此这般,最终需要执行的次数肯定是满足上述要求的最长的子序列操作的次数。对于每一个子序列假如长度为
GG,这个题也就顺利 AC 了,不难做,就是需要细心发现规律才行,代码很容易理解的。由于我又加入了输入外挂,所以效率一下子升到了第一,棒极了。
代码
#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long ll;
const int MAXN = 5e5 + 10;
int n;
int a[MAXN];
template <class T>
inline void scan_d(T &ret)
{
char c;
ret = 0;
while ((c = getchar()) < '0' || c > '9');
while (c >= '0' && c <= '9')
{
ret = ret * 10 + (c - '0'), c = getchar();
}
}
int main()
{
scan_d(n);
for (int i = 1; i <= n; i++)
{
scan_d(a[i]);
}
a[n + 1] = a[n];
int len = 1, ans = 0, l = 1, r = 1;
for (int i = 2; i <= n + 1; i++)
{
if (a[i] != a[i - 1])
{
r = i;
len++;
}
else
{
ans = max(ans, (len - 1) >> 1);
if (len & 1)
{
for (int j = l; j <= r; j++)
{
a[j] = a[l];
}
}
else
{
int mid = (l + r) >> 1;
for (int j = l; j <= r; j++)
{
a[j] = j <= mid ? a[l] : a[r];
}
}
len = 1;
l = r = i;
}
}
printf("%d\n%d", ans, a[1]);
for (int i = 2; i <= n; i++)
{
putchar(' ');
putchar('0' + a[i]);
}
putchar(10);
return 0;
}