Loading

Educational Codeforces Round 103 (Rated for Div. 2)

Educational Codeforces Round 103

A. K-divisible Sum

题意

给定 n , k 构造出长度为 n 的正整数序列, 使得序列的和是 k 的倍数,求最大值的最小值

思路

\(n \le k\) 时候,答案是 \(\lceil \dfrac k n \rceil\) ,当 \(k < n\) 时候, 如果 \(k | n\) 答案是 1 否则答案是 2

向上取整不要用浮点数的 ceil 函数,分子加上分母减一就好, \(\lceil \dfrac k n \rceil = \lfloor \dfrac {k + n - 1} n \rfloor\)

/*
 * @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 \rceil\)

二分答案也是没问题的。

/*
 * @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, " \n"[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] << " \n"[i == n];
	}
	else {
		cout << "NO" << endl;
	}

}

posted @ 2021-01-30 09:58  —O0oO-  阅读(335)  评论(0编辑  收藏  举报