2023 Hubei Provincial Collegiate Programming Contest TF

复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;

const int N = 3e6 + 9;

int a[N];

char b[N];

signed main()
{
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int n;cin >> n;
    for(int i = 0;i <= 2 * n + 1; ++ i)cin >> a[i];

    char ch = 'a';

    b[0] = '&';
    b[1] = '|';
    for(int i = 2, r = 1; i < 2 * n + 2; i++)
    {
      while(r < i + a[i] - 1)
      {
        r++;
        b[r] = b[2*i - r];
      }
      if(i&1) b[i] = '|';
      if(b[i] == 0)
        b[i] = ch, ch = (ch == 'a')?'b':'a';
    }
    for(int i = 2;i <= 2 * n + 1;i += 2)cout << b[i];
    return 0;
}
复制代码

主要解释为什么要交替填a、b:

首先,我们要明确两个性质:

①任何是字母的位置,a[i]>=2

②如果一个|的位置,a[i]=1,那么就说明发生了a和b的交替

对于样例abaaa->&|a|b|a|a|a|

刚开始的时候,i=2,r=1,a[i]必然大于等于2,这时候r会连续填两个数字,这时候因为b[3]还是空的,b[2]就也会复制一个空的,并且r会落在3;

接下来,因为a[3]=1,r就不会移动,然后i又超过了r……

总结规律,我们发现,如果a[i]>1,那么r就会连续移动,超过i的位置;一旦移动到a[i]=1的位置,那么r就会停止移动,等i移过来

i每次只能向前移动1个位置,而也只有a[i]=1的时候,r才不会移动

所以只有a[i]=1的位置,i才可以超过r

也就是只有a和b发生交替的时候,i才可以超过r,而i一旦超过了r,下次填字符的时候就会出现填入一个空字符的情况,因为这个空字符是由于原串中a和b交替导致的,所以这时候就要进行一次ch的变换。

而如果a[i]的值都比较大,那么r就比较大,2*i-r就比较小,每次填入的时候就会用已经填入的字符来填当前的新字符,就不会出现留空的情况,也就不会出现a和b的交替了。

本文作者:Gold_stein

本文链接:https://www.cnblogs.com/smartljy/p/18094284

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Gold_stein  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
🔑
  1. 1 逃离地面 RAD & 三浦透子
逃离地面 - RAD & 三浦透子
00:00 / 00:00
An audio error has occurred.

作词 : 野田洋次郎

作曲 : 野田洋次郎

空飛ぶ羽根と引き換えに 繋ぎ合う手を選んだ僕ら

それでも空に魅せられて 夢を重ねるのは罪か

夏は秋の背中を見て その顔を思い浮かべる

憧れなのか、恋なのか 叶わぬと知っていながら

重力が眠りにつく 1000年に一度の今日

太陽の死角に立ち 僕らこの星を出よう

彼が眼を覚ました時 連れ戻せない場所へ

「せーの」で大地を蹴って ここではない星へ

行こう

もう少しで運命の向こう もう少しで文明の向こう

もう少しで運命の向こう もう少しで

夢に僕らで帆を張って 来たるべき日のために夜を超え

いざ期待だけ満タンで あとはどうにかなるさと 肩を組んだ

怖くないわけない でも止まんない

ピンチの先回りしたって 僕らじゃしょうがない

僕らの恋が言う 声が言う

「行け」と言う