AcWing第 106 场周赛

5032. 字符串操作

给定一个长度为 n 的字符串 s1s2…sn。

你需要对该字符串连续进行 m 次字符替换操作。

每次操作给定一个操作范围 [l,r] 和两个字符 c1、c2,你需要将 sl…sr 中的所有 c1(如果有的话)都替换为 c2。

请你输出所有操作完成后,最终得到的字符串。

输入格式

第一行包含两个整数 n,m。

第二行包含一个长度为 n 的字符串 s1s2…sn,此字符串由小写字母构成。

接下来 m 行,每行包含四个参数 l,r,c1,c2,其中 c1 和 c2 均为小写字母。

输出格式

输出所有操作完成后,最终得到的字符串。

数据范围

前 33 个测试点满足 1≤n,m≤5。
所有测试点满足 1≤n,m≤100,1≤l≤r≤n。

输入样例1:

3 1
aba
1 1 a c

输出样例1:

cba

输入样例2:

5 3
wxhak
3 3 h x
1 5 x a
1 3 w g

输出样例2:

gaaak
#include <iostream>
#include <cstring>

using namespace std;

const int N = 1e5 + 10;

char s[N];

int main()
{
    int n, m;
    cin >> n >> m;
    cin >> s + 1;

    while (m--)
    {
        int l, r;
        char c1, c2;
        cin >> l >> r >> c1 >> c2;

        for (int i = l; i <= r; i++)
        {
            if (s[i] == c1) s[i] = c2;
        }
    }

    cout << s + 1 << endl;

    return 0;
}

5033. 最远距离 

给定一个 n 个点的无向完全图,点的编号 1∼n。

图中所有边的长度已知。

我们规定,两点之间的距离指两点之间的最短路径长度。

请你计算,给定图中距离最远的两个点之间的距离。

输入格式

第一行包含整数 n。

接下来 n 行,每行包含 n 个整数,其中第 i 行第 j 个整数 aij表示连接点 i 和点 j 的边的长度。

输出格式

一个整数,表示给定图中距离最远的两个点之间的距离。

数据范围

前 3 个测试点满足 3≤n≤4 。
所有测试点满足 3≤n≤10 ,1≤aij≤100,aij=aji ,aii=0 。

输入样例1:

3
0 1 1
1 0 4
1 4 0

输出样例1:

2

输入样例2:

4
0 1 2 3
1 0 4 5
2 4 0 6
3 5 6 0

输出样例2:

5
#include <iostream>

using namespace std;

const int N = 15;

int g[N][N];

int main()
{
    int n;
    cin >> n;

    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            cin >> g[i][j];

    for (int k = 1; k <= n; k++)
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                g[i][j] = min(g[i][j], g[i][k] + g[k][j]);

    int res = 0;
    for (int i = 1; i <= n; i++)
        for (int j = 1; j <= n; j++)
            res = max(res, g[i][j]);

    cout << res << endl;

    return 0;
}

5034. 配对 

n 个人参加一场舞会,每个人的性别(男或女)已知。

在开始跳舞之前,需要先给他们进行配对。

初始时,这 n 个人从左到右排成一队,依次编号为 1∼n。

其中,第 i 个人的舞蹈水平为 ai。

当队列中有男有女时,重复以下过程,进行配对:选出当前队列中彼此相邻且舞蹈水平差异最小的一对男女,让他们组成一对舞伴,并离开队列。

注意:

  • 当满足彼此相邻且舞蹈水平差异最小的男女不止一对时,选择最靠左的一对男女进行配对。
  • 队伍始终都是连续的,当一对男女离开队列后,剩下的人会紧缩队伍,保证队伍的连贯。

请你计算,一共可以产生多少对配对,并按配对的产生顺序,将所有配对依次输出。

输入格式

第一行包含整数 n。

第二行包含一个长度为 n 的字符串,字符串中的每个字符要么为 B,要么为 G,其中第 i 个字符用来表示第 i 个人的性别,B 表示男,G 表示女。

第三行包含 n 个整数 a1,a2,…,an。

输出格式

第一行输出一个整数 k,表示可以产生的配对数量。

接下来 k 行,其中第 i 行输出第 i 对产生的配对的男女编号,每对编号在输出时,先输出较小编号,再输出较大编号。

数据范围

前 4 个测试点满足 1≤n≤10 
所有测试点满足 1≤n≤2×105 ,1≤ai≤107 。

输入样例1:

4
BGBG
4 2 4 3

输出样例1:

2
3 4
1 2

输入样例2:

4
BBGG
4 6 1 5

输出样例2:

2
2 3
1 4

输入样例3:

7
BGBGBGB
5 1 2 5 1 2 1

输出样例3:

3
2 3
1 4
5 6
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <iostream>
#include <queue>
#include <cmath>
#include <vector>

using namespace std;

const int N = 100010;
int n;
char str[N];       //存性别字符序列
int a[N];          //存水平    
int l[N], r[N];    //存左边右边是谁
int st[N];         //存是否还在队列里
typedef pair<int, pair<int, int>> PII; //<差值<序号1,序号2>>   
vector<pair<int, int>> m; //存答案

int main()
{
    cin >> n >> str + 1;

    for (int i = 1; i <= n; i++) cin >> a[i];

    for (int i = 1; i <= n; i++) {
        l[i] = i - 1;
        r[i] = i + 1;
    }
    priority_queue<PII, vector<PII>, greater<PII>> heap;
    for (int i = 1; i <= n - 1; i++) {
        if (str[i] != str[i + 1]) {     //初始时把性别相异且相邻的水平差值都加入堆中
            int t = abs(a[i] - a[i + 1]);
            heap.push({ t,{i, i + 1} });
        }
    }

    while (heap.size() && r[0] != n + 1) {  //堆不空且队列不空
        auto t = heap.top();
        int x = t.second.first, y = t.second.second;
        if (st[x] || st[y]){                //x,y已经走了
            heap.pop();
            continue;
        }
        st[x] = st[y] = 1;                  //标记一下
        m.push_back({ x, y });
        heap.pop();

        if (r[y] <= n && l[x] >= 1 && str[l[x]] != str[r[y]]) {  //l[x],r[y]都合法并且性别不同
            int q = abs(a[l[x]] - a[r[y]]);
            heap.push({ q, {l[x], r[y]} });
        }
        r[l[x]] = r[y];                     //更新左右关系
        l[r[y]] = l[x];
    }

    cout << m.size() << endl;               //输出答案

    for (int i = 0; i < m.size(); i++) {
        cout << m[i].first << ' ' << m[i].second << endl;
    }

    return 0;
} 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值