Educational Codeforces Round 103
A. K-divisible Sum
题意
给定 n , k 构造出长度为 n 的正整数序列, 使得序列的和是 k 的倍数,求最大值的最小值
思路
当 (n le k) 时候,答案是 (lceil dfrac k n ceil) ,当 (k < n) 时候, 如果 (k | n) 答案是 1 否则答案是 2
向上取整不要用浮点数的 ceil 函数,分子加上分母减一就好, (lceil dfrac k n ceil = lfloor dfrac {k + n - 1} n floor)
/*
* @Author: zhl
* @LastEditTime: 2021-01-30 09:36:24
*/
/* Author: zhl
* Time: 2021-01-29 22:35:02
**/
void nohack(){
// 佛曰: 你打教育场必不被 hack
//
// _oo0oo_
// o8888888o
// 88" . "88
// (| -_- |)
// 0 = /0
// ___/`---'\___
// .' \| |// '.
// / \||| : |||//
// / _||||| -:- |||||-
// | | \ - /// | |
// | \_| ''---/'' |_/ |
// .-\__ '-' ___/-. /
// ___'. .' /--.-- `. .'___
// ."" '< `.___\_<|>_/___.' >' "".
// | | : `- \`.;` _ /`;.`/ - ` : | |
// `_. \_ __ /__ _/ .-` / /
// =====`-.____`.___ \_____/___.-`___.-'=====
// `=---='
}
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
ll n, k;
int main(){
nohack();
int T;cin >> T;
while (T--) {
cin >> n >> k;
if(k < n){
cout << 1 + (n % k != 0) << endl;
}
else cout << (n + k - 1) / n << endl;
}
}
B. Inflation
思路
全部往 (p_0) 上面怼就可以,处理出前缀和 (s) ,若 ((s[i-1] + ans) * p < a[i] * 100) ,则 ans 加上
(lceil dfrac {a[i] * 100 - (s[i-1] + ans) * k} k ceil)
二分答案也是没问题的。
/*
* @Author: zhl
* @LastEditTime: 2021-01-30 00:56:54
*/
/* Author: zhl
* Time: 2021-01-29 22:35:02
**/
void nohack(){
// 佛曰: 你打教育场必不被 hack
//
// _oo0oo_
// o8888888o
// 88" . "88
// (| -_- |)
// 0 = /0
// ___/`---'\___
// .' \| |// '.
// / \||| : |||//
// / _||||| -:- |||||-
// | | \ - /// | |
// | \_| ''---/'' |_/ |
// .-\__ '-' ___/-. /
// ___'. .' /--.-- `. .'___
// ."" '< `.___\_<|>_/___.' >' "".
// | | : `- \`.;` _ /`;.`/ - ` : | |
// `_. \_ __ /__ _/ .-` / /
// =====`-.____`.___ \_____/___.-`___.-'=====
// `=---='
}
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
int T,n,k;
ll A[N], s[N];
int main(){
nohack();
cin >> T;
while(T--){
cin >> n >> k;
for (int i = 1;i <= n;i++)cin >> A[i], s[i] = s[i - 1] + A[i];
ll ans = 0;
for(int i = n;i >= 2;i--){
ans += max(0ll, (A[i] * 100 - (s[i - 1] + ans) * k + k - 1) / k);
}
cout << ans << endl;
}
}
C. Longest Simple Cycle
思路
求一个类似最大子段和的一个东西,发现分两种情况就可以 A[i] == B[i] 与 A[i] != B[i]
设 f[i] 表示以第 i 条链为最右边的最大环的长度, 若 A[i] != B[i], 则 f[i] 可以和 f[i-1] 合并
否则不能合并
f[2] = C[2] - 1 + 2 + abs(A[2] - B[2])
若 A[i] == B[i]:
f[i] = C[i] - 1 + 2
else:
f[i] = max(abs(A[i] - B[i]) + 2 + C[i] - 1, f[i-1] - abs(A[i] - B[i]) + 2 + C[i] - 1)
/*
* @Author: zhl
* @LastEditTime: 2021-01-29 23:34:39
*/
/* Author: zhl
* Time: 2021-01-29 22:35:02
**/
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
int T, n;
int A[N], B[N], C[N];
ll f[N];
int main() {
cin >> T;
while (T--) {
cin >> n;
for (int i = 1; i <= n; i++) cin >> C[i];
for (int i = 1; i <= n; i++) cin >> A[i];
for (int i = 1; i <= n; i++) cin >> B[i];
f[2] = abs(A[2] - B[2]) + 2 + C[2] - 1;
ll ans = f[2];
for (int i = 3; i <= n; i++) {
if (A[i] == B[i]) {
f[i] = 1ll + C[i];
}
else {
f[i] = max(abs(A[i] - B[i]) + 2ll + C[i] - 1ll, f[i - 1] - abs(A[i] - B[i]) + 1ll +C[i]);
}
ans = max(ans, f[i]);
}
cout << ans << endl;
}
}
D. Journey
思路
对于每个点,所能到达的范围就是一直往左走加上一直往右走的最远距离
预处理出相邻不同的前缀 f 和后缀 g 就可以
/*
* @Author: zhl
* @LastEditTime: 2021-01-30 09:50:28
*/
/* Author: zhl
* Time: 2021-01-29 22:35:02
**/
#include<bits/stdc++.h>
using namespace std;
const int N = 3e5 + 10;
typedef long long ll;
char s[N];
int T, n, f[N], g[N];
int main() {
scanf("%d", &T);
while (T--) {
scanf("%d", &n);
scanf("%s", s + 1);
f[1] = 1;
for (int i = 2;i <= n;i++) f[i] = (s[i] == s[i - 1]) ? 1 : f[i - 1] + 1;
g[n] = 1;
for (int i = n - 1;i >= 1;i--) g[i] = (s[i] == s[i + 1]) ? 1 : g[i + 1] + 1;
for (int i = 1;i <= n + 1;i++) {
int ans = 1;
if (i - 1 >= 1 and s[i - 1] == 'L') ans += f[i - 1];
if (i <= n and s[i] == 'R') ans += g[i];
printf("%d%c", ans, "
"[i == n + 1]);
}
}
}
E. Pattern Matching
思路
注意所有的 (p) 各不相同, (k le 4) ,把字符 '_' 也算进去一共27个字符,可以当作一个27进制的数
由于 (27^4) 约等于 5e5, 可以直接开一个数组表示所有的 (p)
对于一个匹配串 (s) 以及它对应的数字 (mt) ,(s) 最多有 16 个模式串与它匹配((2^k))
(mt) 要在其他模式串的前面,加有向边跑拓扑排序就可以
/*
* @Author: zhl
* @LastEditTime: 2021-01-30 09:57:20
*/
/* Author: zhl
* Time: 2021-01-29 22:35:02
**/
#include<bits/stdc++.h>
using namespace std;
const int N = 2e5 + 10;
typedef long long ll;
int vis[N * 5];
int n, m, k;
int in[N];
string A[N];
vector<int>G[N];
int ans[N], cnt;
int main() {
cin >> n >> m >> k;
for (int i = 1; i <= n; i++) {
string s; cin >> s; A[i] = s;
int idx = 0;
for (int i = k - 1; i >= 0; i--) {
idx = idx * 27;
if (s[i] == '_')idx += 26;
else idx += s[i] - 'a';
}
vis[idx] = i;
}
for (int i = 1; i <= m; i++) {
string s; int mt;
cin >> s >> mt;
for (int i = 0; i < k; i++) {
if (A[mt][i] == '_' or A[mt][i] == s[i])continue;
else {
cout << "NO" << endl;
return 0;
}
}
for (int i = 0; i < 1 << k; i++) {
int idx = 0;
for (int j = k - 1; j >= 0; j--) {
idx = idx * 27;
if ((i >> j) & 1)idx += 26;
else idx += s[j] - 'a';
}
if (vis[idx] != mt and vis[idx]) {
G[mt].push_back(vis[idx]);
in[vis[idx]]++;
}
}
}
queue<int>Q;
for (int i = 1; i <= n; i++) {
if (in[i] == 0)Q.push(i);
}
while (not Q.empty()) {
int now = Q.front(); Q.pop();
ans[++cnt] = now;
for (int v : G[now]) {
in[v]--;
if (in[v] == 0) {
Q.push(v);
}
}
}
if (cnt == n) {
cout << "YES" << endl;
for (int i = 1; i <= n; i++)cout << ans[i] << "
"[i == n];
}
else {
cout << "NO" << endl;
}
}