图形 + 思维
题目传送门:Problem - D - Codeforces
题目大意:给定长度为n的数组a和b,定义b数组的价值为,现可以交换一次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;
}
题目大意:给你两个字符串 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; }

浙公网安备 33010602011771号