• 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 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;
    	}
    
    }
    
    
  • 相关阅读:
    js中有哪些是循环遍历的方法?
    堆内存和栈内存
    Html5和Css3
    PyCharm IDE 的使用
    python基础语法
    数据挖掘书籍简介
    寄存器-2
    汇编基础
    Std::bind()
    手游页游和端游的服务端框架
  • 原文地址:https://www.cnblogs.com/sduwh/p/14348131.html
Copyright © 2020-2023  润新知