CF变红之路_Codeforces Round #401 (Div. 2)

本文分享了CodeForces平台上的四道经典题目解析,包括思维题、字符串处理题、二维数组处理题及字符串排序题。通过实战示例介绍了如何使用C++进行高效编程解决问题,特别强调了预处理、字符串操作等技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

链接:http://codeforces.com/contest/777

A

很好的思维题, 初始位置就三个,然后列举发现周期都为6

操作次数+位置变化
操作次数 0 1 2 3 4 5 
初始位置分别是012时的变化
	0 1 2 2 1 0
	1 0 0 1 2 2
	2 2 1 0 0 1 

很明显发现规律,打表即可
代码

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1000 + 10, inf = 0x3f3f3f3f;

int n, idx;

int ans[] = {0, 1, 2, 2, 1, 0};

void solve() {
    int d = n % 6;
    for(int i = 0; i < 3; i++) {
        int t = (d - i*2 + 6) % 6;
        if(ans[t] == idx) {
            cout << i << endl;
            break;
        }
    }
}

int main()
{
    //freopen("input.txt", "r", stdin);
    while(cin >> n >> idx) {
        solve();
    }
    return 0;
}

B

给出两串数字,每串数字中数字顺序不固定,找到某个顺序使得上面数字按位大于下面数字的次数最少,输出该次数ans1。然后在输出下面数字按位大于上面数字的次数最多的次数ans2。

#include <bits/stdc++.h>
using namespace std;

int a[1010];
int b[1010];

int main() {
    //freopen("input.txt", "r", stdin);
    int n;
    cin  >> n;
    getchar();
    for(int i = 0; i < n; i++) {
        char c = getchar();
        a[i] = c - '0';
    }
    getchar();
    for(int i = 0; i < n; i++) {
        char c = getchar();
        b[i] = c - '0';
    }
    sort(a, a+n);
    sort(b, b+n);
    int i = n-1, j = n-1, ans2 = 0;
    while(i >= 0 && j >= 0) {
        if(b[j] > a[i]) {
            i--, j--, ans2++;
        }
        else i--;
    }
    i = 0, j = 0;
    int ans1 = 0;
    while(i < n && j < n) {
        if(a[i] <= b[j]) {
            i++, j++;
        }
        else {
            j++;
        }
    }
    ans1 = n - i;
    cout << ans1 << endl;
    cout << ans2 << endl;
    return 0;
}

##c(好题)
这道题很好,预处理思想,那个n*m <= 100000的条件也是极好的,二维数组是开不了了,这能开1e5的一维数组,边读入边处理,这个写法我还是看一个大神的博客才学会的。
v[j]记录第j列上一行的读入数据,cd[j] = x记录着第j列第x行到读入的这一行满足非递减的条件,然后d[i] = x说明x 到 i这些行满足非递减的条件。

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e5 + 10;
int v[maxn], d[maxn], cd[maxn];
int n, m;

int main() {
    // freopen("input.txt", "r", stdin);
    cin >> n >> m;
    int tmp;
    for(int i = 1; i <= n; i++) {
        d[i] = i;
        for(int j = 1; j <= m; j++) {
            cin >> tmp;
            if(tmp < v[j])  cd[j] = i;
            v[j] = tmp;
            if(cd[j] < d[i]) d[i] = cd[j];
        }
    }
    int q, l, r;
    cin >> q;
    while(cin >> l >> r) {
        if(d[r] <= l) {
            cout << "Yes" << endl;
        }
        else cout << "No" << endl;
    }
    return 0;
}

又是三道题,下一次努努力多做几道吧,然后花点时间补补这两场的题。
Ps:CF的题真的很不错啊。

补题

D

D真的没想到D题这么水。。。。每行字符串可以删一些后缀使得字典序递增。。。。。从后向前扫一遍就行了,O(n)的复杂度。
代码

#include <bits/stdc++.h>
using namespace std;
string s[500000 + 10];
int main() {
    //freopen("input.txt", "r", stdin);
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    int n;
    while(cin >> n) {
        for(int i =  0; i < n; i++) {
            cin >> s[i];
        }
        for(int i = n-2; i >= 0; i--) {
            int l1 = s[i].size(), l2 = s[i+1].size();
            int cur1=0, cur2 = 0;
            while(cur1 < l1) {
                if(s[i][cur1] == s[i+1][cur2]) {
                    cur1++;
                    cur2++;
                }
                else if(s[i][cur1] > s[i+1][cur2] || cur2 == l2){
                    s[i].resize(cur1);
                    break;
                }
                else {
                    break;
                }
            }
        }
        for(int i = 0; i < n; i++) {
            cout << s[i] << endl;
        }
    }
    return 0;
}
std::ios::sync_with_stdio(false);      
std::cin.tie(0);         // 加快cin的速度
s[i].resize(cur1);     // 改变string的大小也就是保留前面那一段的大小
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值