zoukankan      html  css  js  c++  java
  • Codeforces Round #627 (Div. 3) 题解

    Codeforces Round #627 (Div. 3)

    A. Yet Another Tetris Problem

    题意:给你一堆俄罗斯方块,询问在只有 (1 imes 2) 的方块情况下能否消除所有方块。

    分析:看懂题目比做题还麻烦。

    #define _CRT_SECURE_NO_WARNINGS
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #pragma comment(linker, "/stack:200000000")
    #include <bits/stdc++.h>
    #define SIZE 200010
    #define rep(i, a, b) for (int i = a; i <= b; ++i)
    #define mp make_pair
    #define ll long long
    using namespace std;
    void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
    int n, t, a[SIZE];
    
    int main() {
    	io(); cin >> t;
    	rep(ii, 1, t) {
    		cin >> n;
    		rep(i, 1, n) cin >> a[i];
    		bool f = true;
    		rep(i, 2, n) {
    			if ((a[i] - a[i - 1]) & 1) {
    				f = false;
    				break;
    			}
    		}
    		cout << (f ? "YES
    " : "NO
    ");
    	}
    }
    

    B. Yet Another Palindrome Problem

    题意:询问是否存在长度大于等于三的回文子序列(不连续)。

    分析:由于不连续的条件,我们只需要找是否存在非相邻的相同字符即可。

    #define _CRT_SECURE_NO_WARNINGS
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #pragma comment(linker, "/stack:200000000")
    #include <bits/stdc++.h>
    #define SIZE 200010
    #define rep(i, a, b) for (int i = a; i <= b; ++i)
    #define mp make_pair
    #define ll long long
    using namespace std;
    void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
    int n, t, a[SIZE];
    
    int main() {
    	io(); cin >> t;
    	rep(ii, 1, t) {
    		cin >> n;
    		map<int, vector<int> > MP;
    		bool f = false;
    		rep(i, 1, n) cin >> a[i], MP[a[i]].emplace_back(i);
    		for (auto i : MP) {
    			if (i.second.size() > 2) {
    				f = true;
    				break;
    			}
    			if (i.second.size() == 2 && abs(i.second[0] - i.second[1]) > 1) {
    				f = true;
    				break;
    			}
    		}
    		cout << (f ? "YES
    " : "NO
    ");
    	}
    }
    

    C. Frog Jumps

    题意:给定一个字符串 (s) 。 一只青蛙在 (x=0) 处,一次最大跳跃距离为 (d) ,当它跳到位置 (x=i) 时,如果 (s[i]=R) 那它能继续向右跳,若 (s[i]=L) 那它只能向左跳,询问使得青蛙能够跳到 (x=n+1) 位置的 (d_{min})

    分析:贪心,求两个字符 (R) 之间的最大距离。

    #define _CRT_SECURE_NO_WARNINGS
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #pragma comment(linker, "/stack:200000000")
    #include <bits/stdc++.h>
    #define SIZE 200010
    #define rep(i, a, b) for (int i = a; i <= b; ++i)
    #define mp make_pair
    #define ll long long
    using namespace std;
    void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
    int n, t, a[SIZE];
    
    int main() {
    	io(); cin >> t;
    	rep(ii, 1, t) {
    		string s; cin >> s;
    		s += 'R';
    		int pre = 0, mind = -1;
    		rep(i, 1, s.length()) {
    			if (s[i - 1] == 'R') {
    				mind = max(mind, i - pre);
    				pre = i;
    			}
    		}
    		cout << (mind == -1 ? (s.length() + 1) : mind) << '
    ';
    	}
    }
    

    D. Pair of Topics

    题意:给定两个数组 (a)(b) ,询问满足 (a_i+a_j>b_i+b_j(i<j)) 的二元组 ((i,j)) 数量。

    分析:明显的二分:(a_i+a_j>b_i+b_jLeftrightarrow a_i-b_i>-(a_j-b_j)) 。于是只需要预处理一个数组 (c_i=a_i-b_i)

    #define _CRT_SECURE_NO_WARNINGS
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #pragma comment(linker, "/stack:200000000")
    #include <bits/stdc++.h>
    #define SIZE 200010
    #define rep(i, a, b) for (int i = a; i <= b; ++i)
    #define mp make_pair
    #define ll long long
    using namespace std;
    void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
    ll n, a[SIZE], b[SIZE],ans;
    vector<ll> vec;
     
    int main() {
    	io(); cin >> n;
    	rep(i, 1, n) cin >> a[i];
    	rep(i, 1, n) cin >> b[i];
    	rep(i, 1, n) vec.emplace_back(a[i] - b[i]);
    	sort(vec.begin(), vec.end());
    	rep(i, 0, (vec.size() - 1)) {
    		int now = vec[i];
    		if (now > 0) ans += (n - 1 - i);
    		else {
    			int pos = lower_bound(vec.begin(), vec.end(), 1 - now) - vec.begin();
    			ans += max(0ll, (n - pos));
    		}
    	}
    	cout << ans;
    }
    

    E. Sleeping Schedule

    题意(Vova) 一共要睡觉 (n) 次,每次都会睡满一整天,每天时长 (h) 个小时,如果 (Vova) 的入睡时间在 ([l,r]) 范围内则之称为一次好的睡眠。现在已知 (Vova)(i) 次睡眠前,她能控制自己醒着 (a_i) 或者 (a_i - 1) 个小时。求好的睡眠最大值。

    分析:注意到 (n,hleq 2000) ,直接枚举时间进行 (dp) 。设第 (i) 次睡眠 (j) 时段的最大值为 (dp[i][j]) ,则有: (dp[i][(j+t)modh] = max(dp[i][(j+t)modh],dp[i-1][j]+(lleq (j+t)modhleq r)))((t=a_i) (or) (a_i-1)) 。emmm,好像就结束了。

    #define _CRT_SECURE_NO_WARNINGS
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #pragma comment(linker, "/stack:200000000")
    #include <bits/stdc++.h>
    #define SIZE 2010
    #define rep(i, a, b) for (int i = a; i <= b; ++i)
    #define mp make_pair
    #define ll long long
    using namespace std;
    void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
    int n, h, l, r, ans = -1;
    int a[SIZE], dp[SIZE][SIZE];
    
    int main() {
    	io(); cin >> n >> h >> l >> r;
    	rep(i, 1, n) cin >> a[i];
    	rep(i, 0, 2000) rep(j, 0, 2000) dp[i][j] = -1;
    	dp[0][0] = 0;
    	rep(i, 1, n) {
    		i = i;
    		rep(j, 0, (h - 1)) dp[i][j] = -1;
    		rep(j, 0, (h - 1)) {
    			if (dp[i - 1][j] == -1) continue;
    			rep(t, (a[i] - 1), a[i]) {
    				int k = (j + t) % h;
    				dp[i][k] = max(dp[i][k], dp[i - 1][j] + (l <= k && k <= r));
    			}
    		}
    	}
    	rep(i, 0, h) ans = max(ans, dp[n][i]);
    	cout << ans;
    }
    

    F. Maximum White Subtree

    题意:给定一棵无根树,每个节点都染色为白色或黑色,对每个节点询问:包含当前节点的任意子树中(因为是无根树,实际上就是连通块) (cnt_w-cnt_b) 的最大值,即白色点数减黑色点数的最大值。

    分析:标准的换根树形 (dp) ,我们任取一点作为根,此时对于任意节点我们能够简单地推出以下递推式: (dp_{now}=underset{iin children(now)}sum{max(0,dp[i])}) 。然后考虑换根,我们考虑交换 (now) 节点和他的一个子节点 (to) 之后会发生什么变化:显然这个交换只会影响 (now)(to) 这两个节点,其他节点任然作为子节点不受影响。得到第二组树形 (dp) 转移式:(dp_{now}=dp_{now}-max(0,dp[to]))(dp_{to}=dp_{to}+max(0,dp_{now}))

    #define _CRT_SECURE_NO_WARNINGS
    #pragma GCC optimize(3)
    #pragma GCC optimize("Ofast")
    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    #pragma comment(linker, "/stack:200000000")
    #include <bits/stdc++.h>
    #define SIZE 200010
    #define rep(i, a, b) for (int i = a; i <= b; ++i)
    #define mp make_pair
    #define ll long long
    using namespace std;
    void io() { ios::sync_with_stdio(false); cin.tie(nullptr); cout.tie(nullptr); }
    int n;
    int a[SIZE], dp[SIZE], ans[SIZE];
    vector<int> vec[SIZE];
    
    void dfs(int now, int pa) {
    	dp[now] = a[now];
    	for (auto i : vec[now]) {
    		if (i == pa) continue;
    		dfs(i, now);
    		dp[now] += max(0, dp[i]);
    	}
    }
    
    void dfs2(int now, int pa) {
    	ans[now] = dp[now];
    	for (auto i : vec[now]) {
    		if (i == pa) continue;
    		dp[now] -= max(0, dp[i]);
    		dp[i] += max(0, dp[now]);
    		dfs2(i, now);
    		dp[i] -= max(0, dp[now]);
    		dp[now] += max(0, dp[i]);
    	}
    }
    
    int main() {
    	io(); cin >> n;
    	rep(i, 1, n) {
    		int x; cin >> x;
    		a[i] = (x ? 1 : -1);
    	}
    	rep(i, 1, (n - 1)) {
    		int x, y; cin >> x >> y;
    		vec[x].emplace_back(y);
    		vec[y].emplace_back(x);
    	}
    	dfs(1, 0);
    	dfs2(1, 0);
    	rep(i, 1, n) cout << ans[i] << ' ';
    }
    

    这场 (div3) 好像特别简单。。。

  • 相关阅读:
    基础实验7-2.2 插入排序还是堆排序 (25分)
    进阶实验6-3.1 红色警报 (25分)--并查集
    基础实验3-2.2 单链表分段逆转 (25分)--单链表
    基础实验6-2.2 汉密尔顿回路 (25分)--邻接矩阵
    案例6-1.3 哥尼斯堡的“七桥问题” (25分)--dfs图连通+度判断
    基础实验8-1.1 单身狗 (25分)
    基础实验7-2.3 德才论 (25分)--排序
    基础实验7-2.4 PAT排名汇总 (25分)--结构体排序(快排)
    进阶实验4-3.4 笛卡尔树 (25分)--二叉排序树+堆排序
    基础实验4-2.7 修理牧场 (25分)-堆+哈夫曼树
  • 原文地址:https://www.cnblogs.com/st1vdy/p/12489754.html
Copyright © 2011-2022 走看看