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;
}
