Codeforces Round #753 (Div. 3)题解(待更新)

在这里插入图片描述
这次的战绩。

A题:好像没什么好说的,记录一下每个字符的位置,和上一次的位置就行了

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <set>
#include <queue>

using namespace std;
#define endl '\n'
int pos[30];
string s,ss;
void solve(){
    cin >> s;
    for (int i = 0; i < 26; ++i) {
        pos[s[i] - 'a'] = i;
    }
    cin >> ss;
    char pre = ss[0];
    int res = 0;
    for (int i = 1; i < ss.size(); ++i) {
        res += abs(pos[ss[i] - 'a'] - pos[pre - 'a']);
        pre = ss[i];
    }
    cout << res << endl;
}
signed main(){
    std::ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}

B题:式子推着有点麻烦,不过也只是麻烦而已。
在这里插入图片描述
按上图推一下,得出我们当前的点位要么是 奇 偶偶奇奇偶偶。。。。要么是偶 奇奇偶偶奇奇。。。并且每四个都可以视为一组,每组要么-4要么+4,这跟初值的奇偶有关,然后/4*4求出所有大组的总和,再对第一个和剩下几个特殊处理一下就可以,比较麻烦。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <set>
#include <queue>

using namespace std;
#define endl '\n'
#define int long long
void solve(){
    int a,b;
    cin >> a >> b;
    if (b == 0){
        cout << a << endl;
        return;
    }
    if (a % 2 == 0){
        a --;
        b --;
        a -= b / 4 * 4;
        int mod = b % 4;
        for (int i = b + 1 - mod + 1; i <= b + 1; ++i) {
            if (a & 1){
                a += i;
            }
            else a -= i;
        }
        cout << a << endl;
        return;
    }
    a ++;
    b --;
    a += b / 4 * 4;
    int mod = b % 4;
    for (int i = b + 1 - mod + 1; i <= b + 1; ++i) {
        if (a & 1){
            a += i;
        }
        else a -= i;
    }
    cout << a << endl;
}
signed main(){
    std::ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}

C题:肯定是先从小到大排序最优,因为越小,带给别人的负面影响越小,并且我们还得取得当前的数组最小值。一开始写成了当遍历到a[i] >= 0的时候break,后来发现样例都过不了,因此我们只需一边叠加影响,一边遍历取最佳答案即可。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <set>
#include <queue>

using namespace std;
#define endl '\n'
const int maxn = 2e5 + 5;
int a[maxn],n;
void solve(){
    cin >> n;
    int res = -1e9 - 5;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    sort(a + 1,a + 1 + n);
    int tag = 0;
    for (int i = 1; i <= n; ++i) {
        int now = a[i] - tag;
       res = max(res,now);
       tag += now;
    }
    cout << res << endl;
}
signed main(){
    std::ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}

D题:首先把两种颜色分开然后贪心。红色只能向上取,蓝色只能向下取,那么我们以红色为例,肯定是越小的红色能取到的值越多,越大的红色的价值就越小,因此我们红色从大到小排序,先让最没用的做完自己的贡献。蓝色同理。我们以l,r当作我们现在左右分别需要取到的值,红色只更新r,蓝色只更新l,然后即可得出答案。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <set>
#include <queue>

using namespace std;
#define endl '\n'
#define P pair<int,int>
const int maxn = 2e5 + 5;
int a[maxn];
char s[maxn];
int n;
void solve(){
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> a[i];
    }
    vector<int> u,d,uwait,dwait;
    cin >> s + 1;
    for (int i = 1; i <= n; ++i) {
        if (s[i] == 'B') d.push_back(a[i]);
        else u.push_back(a[i]);
    }
    int l = 1,r = n;
    sort(u.begin(),u.end(),greater<int>());
    sort(d.begin(),d.end());

    for(auto k : u){
        if (k <= r) r--;
    }
    for(auto k : d){
        if (k >= l) l++;
    }
    if (l <= r) cout << "NO" << endl;
    else    cout << "YES" << endl;

}
signed main(){
    std::ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}

E题:将上下,左右分开考虑,x轴上和y轴上分别取最优解,就能取到全局最优解,因为x轴y轴但凡有一个非法,那就无法继续了,因此都必须最优。我们记录历史最高点和历史最低点,当maxx - minn + 1 > n或m时代表非法,撤销印记并输出答案。由于我们以0为基准线,因此输出1-minn即可。

#include <iostream>
#include <cstring>
#include <algorithm>
#include <vector>
#include <math.h>
#include <map>
#include <set>
#include <queue>

using namespace std;
#define endl '\n'
const int maxn = 1e6 + 5;
char s[maxn];
void solve(){
    int n,m;
    cin >> n >> m;
    cin >> s + 1;
    int len = strlen(s + 1);
    int minn = 0,maxx = 0,now = 0;
    for (int i = 1; i <= len; ++i) {
        if (s[i] == 'U') now --;
        if (s[i] == 'D') now ++;
        minn = min(now,minn);
        maxx = max(now,maxx);
        if (maxx - minn + 1 > n){//当前步导致非法,撤销修改
            if (s[i] == 'U') minn ++;
            else maxx --;
            break;
        }
    }
    cout << 1 - minn << ' ';
    minn = 0,maxx = 0,now = 0;
    for (int i = 1; i <= len; ++i) {
        if (s[i] == 'R') now ++;
        if (s[i] == 'L') now --;
        minn = min(now,minn);
        maxx = max(now,maxx);
        if (maxx - minn + 1 > m){
            if (s[i] == 'R') maxx --;
            else    minn ++;
            break;
        }
    }
    cout << 1 - minn << endl;
}
signed main(){
    std::ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    int t;
    cin >> t;
    while (t--) solve();
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值