【AtCoder】Beginner Contest 380-C.Move Segment

题目链接

Problem Statement

You are given a string S S S of length N N N consisting of 0 and 1.

Move the K K K-th 1-block from the beginning in S S S to immediately after the ( K − 1 ) (K-1) (K−1)-th 1-block, and print the resulting string.

It is guaranteed that S S S contains at least K K K 1-blocks.

Here is a more precise description.

  • Let S l ... r S_{l\ldots r} Sl...r denote the substring of S S S from the l l l-th character through the r r r-th character.

  • We define a substring S l ... r S_{l\ldots r} Sl...r of S S S to be a 1-block if it satisfies all of the following conditions:

    • S l = S l + 1 = ⋯ = S r = S_l = S_{l+1} = \cdots = S_r = Sl=Sl+1=⋯=Sr= 1
    • l = 1 l = 1 l=1 or S l − 1 = S_{l-1} = Sl−1= 0
    • r = N r = N r=N or S r + 1 = S_{r+1} = Sr+1= 0
  • Suppose that all 1-blocks in S S S are S l 1 ... r 1 , ... , S l m ... r m S_{l_1\ldots r_1}, \ldots, S_{l_m\ldots r_m} Sl1...r1,...,Slm...rm, where l 1 ≤ l 2 ≤ . . . ≤ l m l_1 \leq l_2 \leq ... \leq l_m l1≤l2≤...≤lm .

    Then, we define the length N N N string T T T, obtained by moving the K K K-th 1-block to immediately after the ( K − 1 ) (K-1) (K−1)-th 1-block, as follows:

    • T i = S i T_i =S_i Ti=Si for 1 ≤ i ≤ r K − 1 1 \leq i \leq r_{K-1} 1≤i≤rK−1
    • T i = T_i = Ti= 1 for r K − 1 + 1 ≤ i ≤ r K − 1 + ( r K − l K ) + 1 r_{K-1} + 1 \leq i \leq r_{K-1} + (r_K - l_K) + 1 rK−1+1≤i≤rK−1+(rK−lK)+1
    • T i = T_i = Ti= 0 for r K − 1 + ( r K − l K ) + 2 ≤ i ≤ r K r_{K-1} + (r_K - l_K) + 2 \leq i \leq r_K rK−1+(rK−lK)+2≤i≤rK
    • T i = S i T_i =S_i Ti=Si for r K + 1 ≤ i ≤ N r_K + 1 \leq i \leq N rK+1≤i≤N

中文题意

问题陈述

你得到一个长度为 N N N 的字符串 S S S ,由' 0 '和' 1 '组成。

将 K K K 第一个' 1 '块从 S S S 开始移动到紧跟在 ( K − 1 ) (K-1) (K−1) 第一个' 1 '块之后,并打印结果字符串。

可以保证 S S S 至少包含 K K K ' 1 ' -块。

这里有一个更精确的描述。

---让 S l ... r S_{l\ldots r} Sl...r 表示 S S S 的子字符串,从 l l l 到 r r r 。

-我们定义 S S S 的子字符串 S l ... r S_{l\ldots r} Sl...r 为' 1 '块,如果它满足以下所有条件:

  • S l = S l + 1 = ⋯ = S r = S_l = S_{l+1} = \cdots = S_r = Sl=Sl+1=⋯=Sr= ' 1 '
  • l = 1 l = 1 l=1 或 S l − 1 = S_{l-1} = Sl−1= ' 0 '
  • r = N r = N r=N 或 S r + 1 = S_{r+1} = Sr+1= ' 0 '
  • 假设 S S S 中所有的"1"-块都是 S l 1 ... r 1 , ... , S l m ... r m S_{l_1\ldots r_1}, \ldots, S_{l_m\ldots r_m} Sl1...r1,...,Slm...rm ,其中 l 1 ≤ l 2 ≤ . . . ≤ l m l_1 \leq l_2 \leq ... \leq l_m l1≤l2≤...≤lm 。

然后,我们定义长度 N N N 字符串 T T T ,通过将 K K K - ' 1 ' 块移动到紧跟在 ( K − 1 ) (K-1) (K−1) -' 1 ' 块之后得到长度 N N N 字符串 T T T ,如下:

  • T i = S i T_i = S_i Ti=Si 为 1 ≤ i ≤ r K − 1 1 \leq i \leq r_{K-1} 1≤i≤rK−1
  • T i = T_i = Ti= 为 r K − 1 + 1 ≤ i ≤ r K − 1 + ( r K − l K ) + 1 r_{K-1} + 1 \leq i \leq r_{K-1} + (r_K - l_K) + 1 rK−1+1≤i≤rK−1+(rK−lK)+1 的' 1 '
  • T i = T_i = Ti= 为 r K − 1 + ( r K − l K ) + 2 ≤ i ≤ r K r_{K-1} + (r_K - l_K) + 2 \leq i \leq r_K rK−1+(rK−lK)+2≤i≤rK 的' 0 '
  • T i = S i T_i = S_i Ti=Si 替换为 r K + 1 ≤ i ≤ N r_K + 1 \leq i \leq N rK+1≤i≤N

Constraints

  • 1 ≤ N ≤ 5 × 1 0 5 1 \leq N \leq 5 \times 10^5 1≤N≤5×105
  • S S S is a string of length N N N consisting of 0 and 1.
  • 2 ≤ K 2 \leq K 2≤K
  • S S S contains at least K K K 1-blocks.

Input

The input is given from Standard Input in the following format:

N N N K K K
S S S

Output

Print the answer.

Sample Input 1

复制代码
15 3
010011100011001

Sample Output 1

复制代码
010011111000001

S S S has four 1-blocks: from the 2nd to the 2nd character, from the 5th to the 7th character, from the 11th to the 12th character, and from the 15th to the 15th character.

Sample Input 2

复制代码
10 2
1011111111

Sample Output 2

复制代码
1111111110

解法

解法一:我们将每一个1块使用 c + + c++ c++中的 pair存储起来,first 表示对应的1 块的开始位置,second表示对应的1块的结束位置。之后重组字符串即可。

cpp 复制代码
#include <iostream>
#include <vector>

#define x first
#define y second

using namespace std;
typedef pair<int, int> PII;

int n, k;
string s;

int main() {
    cin >> n >> k;
    cin >> s;
    
    vector<PII> blocks;

    int start = -1;
    for (int i = 0; i <= n; i ++) {
        if(i < n && s[i] == '1') {
            if(start == -1) start = i;
        } else {
            if(start != -1) {
                blocks.emplace_back(start, i - 1);
                start = -1;
            }
        }
    }

    int k_start = blocks[k - 1].x;
    int k_end = blocks[k - 1].y;

    string t = s;
    string b_str = t.substr(k_start, k_end - k_start + 1);
    t.erase(k_start, k_end - k_start + 1);
    t.insert(blocks[k -2].y + 1, b_str);

    cout << t << endl;
    return 0;
}

解法二:

同样的也是用pair来存储每一个块,只不过first存储当前的块是0还是1second存储当前块的长度,使用循环判断当前是第几个1块,然后交换即可。

cpp 复制代码
#include <iostream>
#include <vector>

using namespace std;
typedef pair<int, int> PII;

int n, k;
string s;

int main() {
    cin >> n >> k;
    cin >> s;
    s += '.';
    vector<PII> b;
    int now = s[0], num = 0;
    for (int i = 0; i < s.size(); i ++) {
        if(s[i] == now) num ++;
        else {
            b.push_back({now - '0', num});
            now = s[i], num = 1;    
        } 
    }

    int cnt = 0; // 统计当前是第几个 1 块
    for (int i = 0; i < b.size(); i ++) {
        if(b[i].first == 1) {
            cnt ++;
            if(cnt == k) {
                swap(b[i], b[i - 1]);
            }
        } 
    }

    for (auto a : b) {
        for (int i = 0; i < a.second; i ++) {
            cout << a.first;
        }
    }
    return 0;
}
相关推荐
水云桐程序员5 小时前
C++可以写手机应用吗
开发语言·c++·智能手机
测试员周周5 小时前
【AI测试智能体】为什么传统测试方法对智能体失效?
开发语言·人工智能·python·功能测试·测试工具·单元测试·测试用例
平凡但不平庸的码农5 小时前
Go Slice 详解
算法·golang
RSTJ_16255 小时前
PYTHON+AI LLM DAY THREETY-NINE
开发语言·人工智能·python
赏金术士6 小时前
Kotlin 从入门到进阶 之函数模块(核心基础)(二)
android·开发语言·kotlin
炸膛坦客8 小时前
嵌入式 - 数据结构与算法:(1-7)数据结构 - 顺序表和链表的对比
数据结构·链表
加号38 小时前
【Qt】 应用程序发布:依赖库拷贝与部署指南
开发语言·qt
Jasmine_llq8 小时前
《B3867 [GESP202309 三级] 小杨的储蓄》
算法·循环遍历·数组累加(模拟)·索引定位·顺序输出
啦啦啦_99998 小时前
案例之 逻辑回归_电信用户流失预测
算法·机器学习·逻辑回归
('-')9 小时前
八股复习2:Java Array list和Linked list
java·开发语言