图形 + 思维

题目传送门:Problem - D - Codeforces

题目大意:给定长度为n的数组a和b,定义b数组的价值为\sum _{i = 1}^{n}|a_{i} - b_{i}|,现可以交换一次b数组中的任意两个元素,求b数组的价值最大值

思路:绝对值问题可以放在数轴上去解决。绝对值即为区间长度。

 

 

ps:摘抄大佬

每个对应的 |ai - bi| 就是一条线段,我们只能交换一次,对于每每两条的线段一共就有如上图四种的情况,所以我们要增大我们的贡献值就只有第二种情况可以满足,通俗的说就是找两条相差最远的两条线段他们产生的贡献值就是 2*(l2 - r1) ,代码如下:#include<bits/stdc++.h>#define int long long

using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 110, mod = 1e9 + 7;
int ans = 0;
int a[N];
int b[N];
void solve() {
    int n;
    cin >> n;
    for (int i = 1; i <= n; i++) cin >> a[i];

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

    int mi_r = 1e9;
    int ma_l = 0;
    ans = 0;
    for (int i = 1; i <= n; i++) {
        if (a[i] > b[i]) swap(a[i], b[i]);
        mi_r = min(mi_r, b[i]);

        ma_l = max(ma_l, a[i]);
        ans += abs(a[i] - b[i]);
    }
    if (mi_r < ma_l) {
        cout << ans + 2 * (ma_l - mi_r)<<"\n";
    }else{
        cout<<ans<<'\n';
    }

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

 Problem - E - Codeforces

题目大意:给你两个字符串 s,t 然后你可以通过以下两个操作使 s 变成0 t:(1)选择s中一个字母删除。 (2)选择 l , r 排序sl ~ sr 。

思路:

扫描 t,维护 s 中可用的字母的位置,如果不存在字母可用则无解.

每当我们使用了 s 中某个字符 x ,那么在 x 之前的字符如果大于x ,那么可以通过排序转移到后面去之后继续使用,否则就无效了(因为跑不到 x 后面肯定就被删掉了),所以只需要每次操作完把无效的字符删掉即可.

大佬详细题解:Codeforces Round 910 (Div. 2) (A~E) - 哔哩哔哩 (bilibili.com)

代码:

#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef pair<int, int> PII;
const int N = 1e6 + 110, mod = 1e9 + 7;
void solve() {
    string s, t;
    int n, m;
    cin >> n >> m;
    cin >> s >> t;

    set<int>pos[26];//可以用栈来存(倒着存,大的下标在下面) 
    
    for (int i = 0; i < n; i++) {
        pos[s[i] - 'a'].insert(i);
    }

    for (int i = 0; i < m; i++) {
        int j = t[i] - 'a';
        if (pos[j].size() == 0) {
            cout << "NO\n";
            return;
        }

        for (int k = 0; k < j; k++) {//找前面比当前小的字符删除
            while (pos[k].size() > 0 && *pos[k].begin() < *pos[j].begin()) {
                pos[k].erase(pos[k].begin());
            }
        }
        pos[j].erase(pos[j].begin());
    }
    cout << "YES\n";
}
signed main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    int T;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}

 

posted @ 2023-11-21 15:29  spiderflower  阅读(27)  评论(0)    收藏  举报