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

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM