Codeforces Round #598 (Div. 3)
作者:互联网
比赛链接:传送门
A. Payment Without Change
代码:
#include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <string> #include <queue> #include <stack> #include <iomanip> #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) #define N 100005 #define M 100005 #define INF 0x3f3f3f3f #define mk(x) (1<<x) // be conscious if mask x exceeds int #define sz(x) ((int)x.size()) #define upperdiv(a,b) (a/b + (a%b>0)) #define mp(a,b) make_pair(a, b) #define endl '\n' #define lowbit(x) (x&-x) using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } template <typename T> inline void write(T x) { int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x; do{++len; c[len] = x%10 + '0';} while (x /= 10); for (int i = len; i >= 1; i--) putchar(c[i]); } template <typename T, typename... Args> inline void write(T x, Args ... args) { write(x), write(args...); } int main() { int T; cin >> T; while (T--) { ll a, b, n, S; read(a, b, n, S); ll cnta = min(a, S/n); ll res = S - cnta * n; if (res <= b) { puts("YES"); } else { puts("NO"); } } return 0; }View Code
B. Minimize the Permutation
暴力。从1到n枚举,每个数尽量地往前和比他大的数交换。并且保证相邻的位置只能换一次。
交换的时候不考虑两者的大小就会有各种奇奇怪怪的bug。
代码:O($n^{2}$)
#include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <string> #include <queue> #include <stack> #include <iomanip> #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) #define N 105 #define M 100005 #define INF 0x3f3f3f3f #define mk(x) (1<<x) // be conscious if mask x exceeds int #define sz(x) ((int)x.size()) #define upperdiv(a,b) (a/b + (a%b>0)) #define mp(a,b) make_pair(a, b) #define endl '\n' #define lowbit(x) (x&-x) using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } template <typename T> inline void write(T x) { int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x; do{++len; c[len] = x%10 + '0';} while (x /= 10); for (int i = len; i >= 1; i--) putchar(c[i]); } template <typename T, typename... Args> inline void write(T x, Args ... args) { write(x), write(args...); } int a[N]; int main() { int T; cin >> T; while (T--) { int n; read(n); for (int i = 1; i <= n; i++) { read(a[i]); } int st = 1; for (int i = 1; i <= n; i++) { for (int j = st; j <= n; j++) { if (a[j] == i) { for (int k = j-1; k >= st; k--) { if (a[k] > a[k+1]) swap(a[k], a[k+1]); else { break; } } st = max(j, i+1); } } } for (int i = 1; i <= n; i++) { printf("%d%c", a[i], " \n"[i==n]); } } return 0; } /* 4 4 1 2 4 3 5 5 4 1 3 2 1 1 4 4 3 2 1 */View Code
C. Platforms Jumping(贪心)
从前到后,贪心地在两岸和木板之间、木板和木板之间插入长度为d-1的“水”,直到“水”的总长度+木板的总长度 = n。
如果“水”的数量超过m+1就是非法的。
否则就得到了一个方案。
代码:O(n)
#include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <string> #include <queue> #include <stack> #include <iomanip> #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) #define N 1005 #define M 1005 #define INF 0x3f3f3f3f #define mk(x) (1<<x) // be conscious if mask x exceeds int #define sz(x) ((int)x.size()) #define upperdiv(a,b) (a/b + (a%b>0)) #define mp(a,b) make_pair(a, b) #define endl '\n' #define lowbit(x) (x&-x) using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } template <typename T> inline void write(T x) { int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x; do{++len; c[len] = x%10 + '0';} while (x /= 10); for (int i = len; i >= 1; i--) putchar(c[i]); } template <typename T, typename... Args> inline void write(T x, Args ... args) { write(x), write(args...); } int c[M]; int ans[N]; vector <int> gaps; int main() { int n, m, d; read(n, m, d); int sum = 0; for (int i = 1; i <= m; i++) { read(c[i]); sum += c[i]; } int r = sum; while (r < n) { if (r + d-1 <= n) { gaps.push_back(d-1); r += d-1; } else { gaps.push_back(n - r); r = n; } if (sz(gaps) > m+1) break; } if (sz(gaps) > m+1) { return puts("NO"), 0; } else { puts("YES"); int idgap = 0, idc = 1; for (int i = 1; i <= n;) { if (idgap < sz(gaps)) { for (int j = 0; j < gaps[idgap]; j++) { ans[i++] = 0; } idgap++; } for (int j = 0; j < c[idc]; j++) { ans[i++] = idc; } idc++; } for (int i = 1; i <= n; i++) { printf("%d%c", ans[i], " \n"[i==n]); } } return 0; }View Code
D. Binary String Minimizing(贪心+双指针)
从左到右每个0依次和当前最左边的1交换,消耗这两个数下标之差的交换次数。
如果次数不够用,就让这个0和最远的能交换的1交换位置。
代码:O(n)
#include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <string> #include <queue> #include <stack> #include <iomanip> #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) #define N 100005 #define M 100005 #define INF 0x3f3f3f3f #define mk(x) (1<<x) // be conscious if mask x exceeds int #define sz(x) ((int)x.size()) #define upperdiv(a,b) (a/b + (a%b>0)) #define mp(a,b) make_pair(a, b) #define endl '\n' #define lowbit(x) (x&-x) using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } template <typename T> inline void write(T x) { int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x; do{++len; c[len] = x%10 + '0';} while (x /= 10); for (int i = len; i >= 1; i--) putchar(c[i]); } template <typename T, typename... Args> inline void write(T x, Args ... args) { write(x), write(args...); } int main() { int q; cin >> q; while (q--) { ll n, k; read(n, k); string s; cin >> s; int st1 = 0; ll resk = k; while (st1 < n && s[st1] == '0') st1++; for (int i = st1; i < n; i++) { if (s[i] == '0') { if (i - st1 <= resk) { resk -= i - st1; swap(s[i], s[st1]); st1++; } else { swap(s[i], s[i - resk]); resk = 0; break; } } } cout << s << endl; } return 0; }View Code
E. Yet Another Division Into Teams(dp+转移路径)
让能力相近的选手组队是最好的。
组成人数x >= 6人的队伍不如把能力最大的3人提出来组成1个3人队+1个x-3人队,所以只用考虑3、4、5人的队伍。
对数组a排序后,设$f_{i}$表示前i个人组完队后得到的最小的total diversity。
对每个i考虑$f_{i}从f_{i-3}、f_{i-4}、f_{i-5}$转移,因为数组a已经排过序了,i-j产生的diversity就是a[i] - a[i-j+1]。
记录转移时的前驱。最后相同区间内的人都分到同一组。
代码:O(n)
#include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <string> #include <queue> #include <stack> #include <iomanip> #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) #define N 200005 #define M 100005 #define INF 0x3f3f3f3f #define mk(x) (1<<x) // be conscious if mask x exceeds int #define sz(x) ((int)x.size()) #define upperdiv(a,b) (a/b + (a%b>0)) #define mp(a,b) make_pair(a, b) #define endl '\n' #define lowbit(x) (x&-x) using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } template <typename T> inline void write(T x) { int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x; do{++len; c[len] = x%10 + '0';} while (x /= 10); for (int i = len; i >= 1; i--) putchar(c[i]); } template <typename T, typename... Args> inline void write(T x, Args ... args) { write(x), write(args...); } struct Node{ ll val; int id; bool operator < (const Node& x) const { return val < x.val; } }a[N]; ll sum[N]; ll f[N]; int pre[N]; int ans[N]; int main() { int n; read(n); sum[0] = 0; for (int i = 1; i <= n; i++) read(a[i].val), a[i].id = i, sum[i] = sum[i-1] + a[i].val; sort(a+1, a+1+n); memset(f, 0x3f, sizeof f); f[0] = 0; pre[0] = -1; for (int i = 3; i <= n; i++) { for (int j = 3; j <= 5; j++) { if (i-j >= 0 && f[i] > f[i-j] + a[i].val - a[i-j+1].val) { f[i] = f[i-j] + a[i].val - a[i-j+1].val; pre[i] = i-j; } } } int tot = 0; for (int i = n; i >= 1; i = pre[i]) { ++tot; for (int j = i; j > pre[i]; j--) { ans[a[j].id] = tot; } } cout << f[n] << ' ' << tot << endl; for (int i = 1; i <= n; i++) { printf("%d%c", ans[i], " \n"[i == n]); } return 0; }View Code
F. Equalizing Two Strings(逆序对)
因为交换次数任意,所以len > 2的操作都可以看作若干次len = 2的操作的叠加。不妨只考虑len = 2的操作。
①:如果字母构成不同一定不行。
②:如果字母构成相同,并且至少有一个字母重复出现,一定可行。可以先把s中两个相同的字母换到最左边,然后s中选择区间[1,2]时,t串中任意相邻的两个字母可以无限交换。
③:如果字母构成相同,并且没有重复字母。在s中选择一个len = 2的区间,再在t中选择一个len = 2的区间,就相当于在t中选择两个len = 2的区间。
那么只要t能在偶数次len = 2的操作中得到s,就可行,否则就不可行。(此时t长度最多26,冒泡排序就行)
代码:O(n + $26^{2}$)
#include <iostream> #include <map> #include <algorithm> #include <cstdio> #include <cstring> #include <set> #include <vector> #include <string> #include <queue> #include <stack> #include <iomanip> #define fast ios::sync_with_stdio(false), cin.tie(0), cout.tie(0) #define N 100005 #define M 100005 #define INF 0x3f3f3f3f #define mk(x) (1<<x) // be conscious if mask x exceeds int #define sz(x) ((int)x.size()) #define upperdiv(a,b) (a/b + (a%b>0)) #define mp(a,b) make_pair(a, b) #define endl '\n' #define lowbit(x) (x&-x) using namespace std; typedef long long ll; typedef double db; /** fast read **/ template <typename T> inline void read(T &x) { x = 0; T fg = 1; char ch = getchar(); while (!isdigit(ch)) { if (ch == '-') fg = -1; ch = getchar(); } while (isdigit(ch)) x = x*10+ch-'0', ch = getchar(); x = fg * x; } template <typename T, typename... Args> inline void read(T &x, Args &... args) { read(x), read(args...); } template <typename T> inline void write(T x) { int len = 0; char c[21]; if (x < 0) putchar('-'), x = -x; do{++len; c[len] = x%10 + '0';} while (x /= 10); for (int i = len; i >= 1; i--) putchar(c[i]); } template <typename T, typename... Args> inline void write(T x, Args ... args) { write(x), write(args...); } int n; string s, t; int cnts[30], cntt[30]; bool solve() { for (int i = 0; i < 26; i++) { if (cnts[i] != cntt[i]) return false; } for (int i = 0; i < 26; i++) { if (cnts[i] > 1) return true; } int cnt = 0; for (int i = 0; i < n; i++) { for (int j = i; j < n; j++) { if (t[j] == s[i]) { for (int k = j-1; k >= i; k--) { swap(t[k+1], t[k]); cnt++; } } } } return cnt % 2 == 0; } int main() { int q; cin >> q; while (q--) { cin >> n; cin >> s >> t; memset(cnts, 0, sizeof cnts); memset(cntt, 0, sizeof cntt); for (int i = 0; i < n; i++) { cnts[s[i]-'a']++; cntt[t[i]-'a']++; } bool ans = solve(); if (ans) puts("YES"); else puts("NO"); } return 0; }View Code
标签:ch,int,598,Codeforces,len,read,Div,include,define 来源: https://www.cnblogs.com/Lubixiaosi-Zhaocao/p/11797744.html