Coderforces #Div2 715 A~E 题解

A

奇数和偶数分别相邻即可

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <cctype>
#include <cmath>
#include <cstring>
#include <stack>
#include <tuple>
#include <numeric>
#include <map>
#include <set>
 
#define forn(i, n) for(int i = 0; i < int(n); ++i)
#define debug(i) cout << "<< " << i << " >>" << endl;
#define pi acos(-1)
 
using namespace std;
using ll = long long;
 
template <typename T> void read(T & x){
    x = 0; int op = 1; char ch = getchar();
    while (!isdigit(ch)){ if (ch == '-') op = -1; ch = getchar();}
    while (isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48); ch = getchar();}
    x*= op;
}

void solve(){
    int n;
    read(n);
    vector<int> odd;
    vector<int> even;
    for (int i = 0, x; i < n; ++i) {
        read(x);
        if (x & 1){
            odd.push_back(x);
        }else{
            even.push_back(x);
        }
    }
    for (int e : odd) {
        cout << e << " ";
    }
    for (int e : even){
        cout << e << " ";
    }
    cout << '\n';
}
 
signed main(){
    int t;
    read(t);
    while (t--){
        solve();
    }
}

B

维护前缀和,正着倒着各扫一遍,确保每个扫到的M,前面(后面)T的数量要大于M的数量

const int N = 1e5 + 100;
int sum[N];
char s[N];
 
int get(int l, int r){
    return sum[r] - sum[l - 1];
}
 
void solve() {
    int n;
    read(n);
    memset(sum, 0, sizeof sum);
    scanf("%s", s + 1);
    int t = 0, m = 0;
    for (int i = 1; i <= n; ++i) {
        if (s[i] == 'T') {
            t++;
            sum[i] = 1;
        } else {
            m++;
        }
    }
 
    for (int i = 1; i <= n; ++i) {
        sum[i] += sum[i - 1];
    }
 
    if (t != 2*m){
        cout << "NO" << endl;
        return;
    }
    int flag = 1;
    m = 0;
    for (int i = 1; i <= n; ++i) {
        if (s[i] == 'M'){
            m++;
            if (get(1, i) < m){
                flag = 0;
                break;
            }
        }
    }
 
    m = 0;
    for (int i = n; i >= 1; --i) {
        if (s[i] == 'M'){
            m++;
            if (get(i, n) < m){
                flag = 0;
                break;
            }
        }
    }
    if (flag){
        cout << "YES" << endl;
    }else{
        cout << "NO" << endl;
    }
}
signed main(){
    int t;
    read(t);
    while (t--){
        solve();
    }
}

C

排序后区间动态规划,注意开long long

#define int long long
void solve() {
    read(n);
    for (int i = 1; i <= n; ++i) {
        read(a[i]);
    }
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= n; ++j) {
            dp[i][j] = 1e12;
        }
    }
 
    for (int i = 0; i <= n; ++i) {
        dp[i][i] = 0;
    }
 
    for (int len = 2; len <= n; ++len) {
        for (int i = 1; i <= n - len + 1; ++i) {
            int j = i + len - 1;
            dp[i][j] = min(dp[i][j], dp[i][j - 1] + a[j] - a[i]);
            dp[i][j] = min(dp[i][j], dp[i + 1][j] + a[j] - a[i]);
        }
    }
    cout << dp[1][n] << endl;
}
 
signed main(){
    int t = 1;
    //read(t);
    while (t--){
        solve();
    }
}

D

三指针?p0, p1, p2至少有一对相等,更新到最后的指向分别是n, t, s
那么res的长度为(2n + s + t)/ 2
于是加上剩下的一段,容易证明
(2n + s + t)/ 2 + (2n - max(s, t)) <= 3*n
于是可构造结果

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cctype>
#include <vector>
 
using namespace std;
using ll = long long;
 
template <typename T> void read(T & x){
    x = 0; int op = 1; char ch = getchar();
    while (!isdigit(ch)){ if (ch == '-') op = -1; ch = getchar();}
    while (isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48); ch = getchar();}
    x*= op;
}
 
void solve(){
    string s[3];
    int n;
    read(n);
    for (int i = 0; i < 3; ++i) {
        cin >> s[i];
    }
    string res;
    int p[3] = {0, 0, 0};
    while (*max_element(p, p + 3) != 2*n){
        if (s[0][p[0]] == s[1][p[1]]){
            res.push_back(s[0][p[0]]);
            p[0]++;
            p[1]++;
        }else if (s[0][p[0]] == s[2][p[2]]){
            res.push_back(s[0][p[0]]);
            p[0]++;
            p[2]++;
        }else if (s[1][p[1]] == s[2][p[2]]){
            res.push_back(s[1][p[1]]);
            p[1]++;
            p[2]++;
        }
    }
    vector<int> num(p, p + 3);
    sort(num.begin(), num.end());
    int pos = num[1];
    int id = -1;
    for (int i = 0; i < 3; ++i) {
        if (p[i] == pos) id = i;
    }
    for (int i = pos; i < 2*n; ++i) {
        res.push_back(s[id][i]);
    }
    cout << res << '\n';
}
signed main(){
    int cases;
    read(cases);
    while (cases--){
        solve();
    }
}

E

对于almost sorted 长度为n的序列,按字典顺序从小到大,有
1, …
2, 1…
3, 2, 1…
n, n - 1, n -2, … 1
不难得出一下的递推公式
(a[n]为方案总数
对于1, …, 后面的2 ~ n 可看作1 ~ n - 1的almost sorted排列整体加一)

/*
 * 
 * a[n] = a[n - 1] + a[n - 2] + ... + a[1] + a[0]
 * a[n] = 2^(n-1)
 * a[0] = 1
 */

递归求解即可, 不过要注意n的范围1e5,直接算2^n行不通,需要一些特殊的处理,详见代码

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cctype>
#include <vector>

using namespace std;
using ll = long long;

template <typename T> void read(T & x){
    x = 0; int op = 1; char ch = getchar();
    while (!isdigit(ch)){ if (ch == '-') op = -1; ch = getchar();}
    while (isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48); ch = getchar();}
    x*= op;
}

/*
 * a[n] = a[n - 1] + a[n - 2] + ... + a[1]
 * a[n] = 2^n-1
 *
 */

int get(vector<int> &res, int delta, ll n, ll k){
    if (k == 0 || n == 0){
        return 1;
    }
    ll tot = 1;
    for (ll i = 1; i <= n - 2; ++i) {
        tot *= 2;
        if (tot >= k){
            break;
        }
    }
    if (tot > k){
        res.push_back(1 + delta);
        get(res, delta + 1, n - 1, k);
        return 1;
    }

    int cnt = 1;
    while (k > tot && tot){
        k -= tot;
        tot /= 2;
        cnt++;
    }
    for (int i = cnt; i >= 1; --i) {
        res.push_back(i + delta);
    }
    get(res, delta + cnt, n - cnt, k);
    return 1;
}

void solve(){
    ll n, k;
    read(n), read(k);

    ll tot = 1;
    for (int i = 0; i < n - 1; ++i) {
        tot *= 2;
        if (tot >= k){
            break;
        }
    }
    if (k > tot){
        printf("-1\n");
        return;
    }
    vector<int> res;
    if (get(res, 0, n, k)){
        for (int i : res) printf("%d ", i);
    }
    printf("\n");
}

signed main(){
    int cases;
    read(cases);
    while (cases--){
        solve();
    }
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。
Go语言(也称为Golang)是由Google开发的一种静态强类型、编译型的编程语言。它旨在成为一门简单、高效、安全和并发的编程语言,特别适用于构建高性能的服务器和分布式系统。以下是Go语言的一些主要特点和优势: 简洁性:Go语言的语法简单直观,易于学习和使用。它避免了复杂的语法特性,如继承、重载等,转而采用组合和接口来实现代码的复用和扩展。 高性能:Go语言具有出色的性能,可以媲美C和C++。它使用静态类型系统和编译型语言的优势,能够生成高效的机器码。 并发性:Go语言内置了对并发的支持,通过轻量级的goroutine和channel机制,可以轻松实现并发编程。这使得Go语言在构建高性能的服务器和分布式系统时具有天然的优势。 安全性:Go语言具有强大的类型系统和内存管理机制,能够减少运行时错误和内存泄漏等问题。它还支持编译时检查,可以在编译阶段就发现潜在的问题。 标准库:Go语言的标准库非常丰富,包含了大量的实用功能和工具,如网络编程、文件操作、加密解密等。这使得开发者可以更加专注于业务逻辑的实现,而无需花费太多时间在底层功能的实现上。 跨平台:Go语言支持多种操作系统和平台,包括Windows、Linux、macOS等。它使用统一的构建系统(如Go Modules),可以轻松地跨平台编译和运行代码。 开源和社区支持:Go语言是开源的,具有庞大的社区支持和丰富的资源。开发者可以通过社区获取帮助、分享经验和学习资料。 总之,Go语言是一种简单、高效、安全、并发的编程语言,特别适用于构建高性能的服务器和分布式系统。如果你正在寻找一种易于学习和使用的编程语言,并且需要处理大量的并发请求和数据,那么Go语言可能是一个不错的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值