Codeforces Round #617 (Div. 3)
A. Array with Odd Sum
签到。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/4 22:36:18
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2000 + 5;
int n;
int a[N];
void run(){
int cnt = 0;
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
if(a[i] & 1) ++cnt;
}
if(cnt == 0) cout << "NO" << '\n';
else {
if(cnt % 2 == 0 && n == cnt) cout << "NO" << '\n';
else cout << "YES" << '\n';
}
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
B. Food Buying
贪心即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/4 22:41:54
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 1e5 + 5;
void run(){
int n; cin >> n;
ll ans = 0;
while(n) {
int t = n / 10 * 10;
if(t == 0) t = n;
ans += t;
n = n - t + n / 10;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
C. Yet Another Walking Robot
用个\(map\)记录一下走到某一坐标的最晚时刻,然后直接维护答案就行。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/4 22:48:22
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
int n;
char s[N];
void run(){
cin >> n >> (s + 1);
map <int, map<int, int>> mp;
int x = 0, y = 0;
mp[x][y] = 0;
int ans = INF, l, r;
for(int i = 1; i <= n; i++) {
if(s[i] == 'L') --x;
if(s[i] == 'R') ++x;
if(s[i] == 'U') ++y;
if(s[i] == 'D') --y;
if(mp[x].find(y) == mp[x].end()) {
mp[x][y] = i;
} else {
if(i - mp[x][y] < ans) {
ans = i - mp[x][y];
l = mp[x][y] + 1, r = i;
}
mp[x][y] = i;
}
}
if(ans == INF) cout << -1 << '\n';
else cout << l << ' ' << r << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
int T; cin >> T;
while(T--) run();
return 0;
}
D. Fight with Monsters
因为每次先手都是固定的,相当于打每只怪兽都是独立的。所以直接贪心即可。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/4 22:59:21
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
int n, a, b, k;
int h[N];
void run(){
int ans = 0;
vector <int> v;
for(int i = 1; i <= n; i++) {
cin >> h[i];
int r = (h[i] - 1) % (a + b) + 1;
if(r <= a) {
++ans;
} else {
int need = (r - 1) / a;
v.push_back(need);
}
}
sort(all(v));
for(auto it : v) {
if(k >= it) k -= it, ++ans;
}
cout << ans << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n >> a >> b >> k) run();
return 0;
}
E1. String Coloring (easy version)
题意:
给出一个字符串,现在给每个位置进行染色,至多用两种颜色。
然后可以执行任意次操作:交换两个相邻的且颜色不相同的字符。
问执行任意次操作后,得到的字符串是否能有序,如果能,给出一种染色方案。
思路:
显然每个字符只会和其前面比他大的字符有关,那么直接暴力枚举,根据前面的颜色来确定当前的颜色就行。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/4 23:23:04
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 200 + 5;
int n;
char s[N];
int c[N];
void run(){
memset(c, 0, sizeof(c));
cin >> (s + 1);
for(int i = 1; i <= n; i++) {
int cnt = 0;
for(int j = 1; j < i; j++) {
if(s[j] > s[i]) {
if(c[i] == c[j]) {
c[i] = c[j] ^ 1;
++cnt;
}
}
}
if(cnt > 1) {
cout << "NO" << '\n';
return;
}
c[i] = cnt;
}
cout << "YES" << '\n';
for(int i = 1; i <= n; i++) cout << c[i];
cout << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}
E2. String Coloring (hard version)
题意:
题意大致和E1相同,只是现在可以染多种颜色,求最终最少染了多少种颜色,并给出一种染色方案。
思路:
显然每个字符只会和其前面比它大的字符有关。
暴力的想法就是枚举每个比它大的字符,最后对每个字符的取值取并然后求mex。
注意到如果有多个字符都等于相同的颜色,显然越大的字符越有用。那么我们对\(1\)~\(n\)中的每个数维护“当前颜色与之相等且最大的字符”。
那么我们最终求的就是第一个取值小于等于当前字符的位置。
可以用权值线段树等乱七八糟的东西来维护。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/4 23:48:52
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 2e5 + 5;
int n;
char s[N];
int c[N];
int minv[N << 2];
int query(int o, int l, int r, int v) {
if(l == r) return l;
int mid = (l + r) >> 1;
if(minv[o << 1] <= v) return query(o << 1, l, mid, v);
return query(o << 1|1, mid + 1, r, v);
}
void update(int o, int l, int r, int p, int v) {
if(l == r) {
minv[o] = max(v, minv[o]);
return;
}
int mid = (l + r) >> 1;
if(p <= mid) update(o << 1, l, mid, p, v);
else update(o << 1|1, mid + 1, r, p, v);
minv[o] = min(minv[o << 1], minv[o << 1|1]);
}
void run(){
cin >> (s + 1);
for(int i = 1; i <= n; i++) {
int p = query(1, 1, n, s[i] - 'a');
c[i] = p;
update(1, 1, n, p, s[i] - 'a');
}
int Max = *max_element(c + 1, c + n + 1);
cout << Max << '\n';
for(int i = 1; i <= n; i++) cout << c[i] << ' ';
cout << '\n';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}
F. Berland Beauty
题意:
给出一颗\(n,n\leq 5000\)个结点的无向树,其树边上有权值范围为\([1,10^6]\),但现在不知道这些权值。
同时给出\(m\)条信息,每个信息为\(a_i,b_i,c_i\),即树上\(a_i\)到\(b_i\)的路径中最小权值为多少。
现在就要通过这些信息构造出一种合法的权值序列,如果出现不合法的情况输出\(-1\)。
思路:
对于每个信息,直接暴力给路径上的每条边打标记,若一条树边的权值为\(x\),意味着这条边权值最小为\(x\)。
处理完所有信息后再检验一次看是否合法,若不合法则说明出现矛盾,合法的话直接输出即可。
注意没处理到的边要随便赋一个值。
Code
/*
* Author: heyuhhh
* Created Time: 2020/2/5 0:09:26
*/
#include <iostream>
#include <algorithm>
#include <cstring>
#include <vector>
#include <cmath>
#include <set>
#include <map>
#include <queue>
#include <iomanip>
#define MP make_pair
#define fi first
#define se second
#define sz(x) (int)(x).size()
#define all(x) (x).begin(), (x).end()
#define INF 0x3f3f3f3f
#define Local
#ifdef Local
#define dbg(args...) do { cout << #args << " -> "; err(args); } while (0)
void err() { std::cout << '\n'; }
template<typename T, typename...Args>
void err(T a, Args...args) { std::cout << a << ' '; err(args...); }
#else
#define dbg(...)
#endif
void pt() {std::cout << '\n'; }
template<typename T, typename...Args>
void pt(T a, Args...args) {std::cout << a << ' '; pt(args...); }
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
//head
const int N = 5000 + 5;
int n, m;
vector <int> G[N];
int deep[N], fa[N];
int f[N], e[N][N], id[N][N];
int a[N], b[N], c[N];
void dfs(int u, int p) {
deep[u] = deep[p] + 1;
fa[u] = p;
for(auto v : G[u]) {
if(v != p) dfs(v, u);
}
}
void dfs2(int u, int p) {
for(auto v : G[u]) {
if(v != p) {
dfs2(v, u);
f[id[u][v]] = e[u][v];
}
}
}
void run(){
for(int i = 1; i < n; i++) {
int u, v; cin >> u >> v;
G[u].push_back(v);
G[v].push_back(u);
id[u][v] = id[v][u] = i;
}
dfs(1, 0);
cin >> m;
for(int i = 1; i <= m; i++) cin >> a[i] >> b[i] >> c[i];
for(int i = 1; i <= m; i++) {
if(deep[a[i]] < deep[b[i]]) swap(a[i], b[i]);
int k1 = a[i], k2 = b[i], g = c[i];
while(deep[k1] != deep[k2]) {
int to = fa[k1];
if(e[to][k1] <= g) e[to][k1] = e[k1][to] = g;
k1 = to;
}
while(k1 != k2) {
int to1 = fa[k1], to2 = fa[k2];
if(e[to1][k1] <= g) e[to1][k1] = e[k1][to1] = g;
if(e[to2][k2] <= g) e[to2][k2] = e[k2][to2] = g;
k1 = to1, k2 = to2;
}
}
for(int i = 1; i <= m; i++) {
if(deep[a[i]] < deep[b[i]]) swap(a[i], b[i]);
int k1 = a[i], k2 = b[i], g = c[i];
int Min = INF;
while(deep[k1] != deep[k2]) {
int to = fa[k1];
Min = min(Min, e[to][k1]);
k1 = to;
}
while(k1 != k2) {
int to1 = fa[k1], to2 = fa[k2];
Min = min(Min, min(e[to1][k1], e[to2][k2]));
k1 = to1, k2 = to2;
}
if(Min != g) {
cout << -1 << '\n';
return;
}
}
dfs2(1, 0);
for(int i = 1; i < n; i++) if(!f[i]) f[i] = 1000000;
for(int i = 1; i < n; i++) cout << f[i] << ' ';
}
int main() {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cout << fixed << setprecision(20);
while(cin >> n) run();
return 0;
}
重要的是自信,一旦有了自信,人就会赢得一切。