回家vp Codeforces Round 776 (Div. 3)

文章介绍了如何通过字符串操作将一个字符串转换成特定字符,以及如何计算给定函数在特定范围内的最大值。还讨论了嵌套段划分问题中最小权值的计算方法。
摘要由CSDN通过智能技术生成

 A - Deletions of Two Adjacent Letters

题意:给你一个字符串s,和字符c,你可以重复以下操作(也可以不操作):每次选择两个相邻的字母删除,问s是否可以通过上述操作变成c

思路:通过样例可以发现当c位于s中的奇数位置时,可以通过操作变成c,所以只需要看一下c在s中的位置并且特判一下s只有一个字符的情况即可

代码:

void solve()
{
    string s;
    cin >> s;
    if (s.size() == 1)
    {
        string c;
        cin >> c;
        if (s == c)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
    else
    {
        s = " " + s;
        bool flag = false;
        char c;
        cin >> c;
        for (int i = 1; i < s.size(); i++)
            if (s[i] == c && i % 2 == 1)
                flag = true;
        if (flag)
            cout << "YES" << endl;
        else
            cout << "NO" << endl;
    }
}

 B - DIV + MOD

题意:给定一个函数f(x)=x/a+xmoda.其中a是给定的数,给出x可以取的范围为[l,r],求在这个范围内的最大f(x)的值

思路:这个题其实挺容易想到当模数为a-1时f(x)是取最大的,但是需要考虑特殊情况,如当l/a==r/a(并不是区间长度小于a),(因为在这个区间内f(x)的值是单调递增的),以及r%a==a-1的时候,其他情况都是r向前进1,再令模数为a-1

代码:

void solve()
{
    int l, r, a;
    cin >> l >> r >> a;
    // 求x/a+x%a的最大值,就是找规律,如果区间长度小于a或者是r+1刚好整除a,说明r%a==a-1则r时取最大,其他情况都向前进1
    int ans = 1;
    if (l / a == r / a || r % a == a - 1)
        ans = r / a + r % a;
    else
        ans = r / a - 1 + a - 1;
    cout << ans << endl;
}

C - Weight of the System of Nested Segments

题意:给出一个嵌套段的定义(类似区间套),给出m个坐标以及对应的权值,要求恰好将这m个坐标分成n个嵌套段的的权值最小,同时输出权值最小的情况下各个段的两个端点的坐标

思路:通过样例解释可以看出一个段的权值,只算这个段的两个端点的权值,所以我们可以开一个结构体,记录每个点的坐标,对应的权值,以及读入的下标,然后先根据权值排序,再根据坐标排序。前2*n个坐标对应的权值就是这个最小段的权值,然后坐标的话直接按照第一个和最后一个形成一段,第二个和倒数第二个形成一段的方式,一段套一段的形式即可,再输出对应坐标

代码:

#define int long long
const int N = 2e5 + 10;
struct node // 先按照权值排再按照坐标排
{
    int val; // 权值
    int pos; // 坐标
    int id;  // 输入的顺序
} a[N];
bool cmp(node a, node b)
{
    return a.val < b.val;
}
bool cmp1(node a, node b)
{
    return a.pos < b.pos; // 位置从小到大
}
void solve()
{
    int n, m; // 分成n块,m个坐标和其对应的权值
    cin >> n >> m;
    for (int i = 1; i <= m; i++)
        cin >> a[i].pos >> a[i].val, a[i].id = i; // 记录输入顺序,后面输出的时候按照输入顺序输出
    sort(a + 1, a + m + 1, cmp);                  // 先按照权值从小到大排
    sort(a + 1, a + 2 * n + 1, cmp1);
    int ans = 0;
    for (int i = 1; i <= 2 * n; i++)
        ans += a[i].val;
    cout << ans << endl;
    for (int i = 1; i <= n; i++)
        cout << a[i].id << " " << a[2 * n - i + 1].id << endl;
    cout << endl;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值