Codeforces Round #756 (Div. 3) 题解
A. Make Even
题目大意:给你一个数n,现在你可以选择一个长度l,让这个数的前l位数交换。请你用最少的交换次数(可以为0),使n变成偶数。如果无法达到,输出-1。
解题思路:答案只可能是-1,0,1,2,根据偶数位所出现的位置决定。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
int work() {
int n, m = 0, flag = 0;
cin >> n;
if (n % 2 == 0) return 0;
while(n > 0) {
m = m * 10 + n % 10;
if (n % 10 % 2 == 0) flag = 1;
n /= 10;
}
if (flag == 0) return -1;
if (m % 2 == 0) return 1;
return 2;
}
int main()
{
int T;
cin >> T;
while(T--) {
cout << work() << endl;
}
return 0;
}
B. Team Composition: Programmers and Mathematicians
题目大意:有a个计算机科学家和b个数学家,现在你需要给这些人组队。组队条件:1. 每个队伍必须有4人;2.每个队伍至少有1个数学家和1个计算机科学家。问最多能组多少个队伍。
解题思路:实在懒得去想贪心了,直接二分答案。每个队伍先安排一个数学家和一个计算机科学家,然后剩下的队员随意安排即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
int a, b;
bool check(int x) {
int c = a - x, d = b - x;
if (c >= 0 && d >= 0 && (c+d)/2 >= x) return 1;
else return 0;
}
void work() {
cin >> a >> b;
int l = 0, r = (a+b)/4;
while(l <= r) {
int mid = (l+r) / 2;
if (check(mid)) l = mid + 1;
else r = mid - 1;
}
cout << l-1 << endl;
}
int main()
{
int T;
cin >> T;
while(T--) {
work();
}
return 0;
}
C. Polycarp Recovers the Permutation
题目大意:有一个1-n的排列p,现在你要构造一个新的数组a。每次你需要比较p最左边的元素和p最右边的元素。如果左边的比较小,那么将这个元素插入a的最左边;如果右边的比较小,插入a的最右边,同时p中的这个元素删除。当p还剩最后一个元素的时候,你可以选择插入a的左边或者右边。
现在给你一个最终的a,请你找出任意一种p,或者无解输出-1。
解题思路:贪心和构造法。因为是1-n的排列,所以不用担心数字会重复。最大的那个数字n一定最后出去,因此你需要判断n是否在队首或者队尾。如果n在队首的话,先输出n,再把a中下标2~n-1的数字倒过来输出即可。如果n在队尾的话,把a中下标1~n-1倒过来输出,再输出0即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
using namespace std;
int n, a[2000005];
void work() {
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
if (a[1] == n) {
cout << a[1];
for(int j = n; j >= 2; j--) cout << ' ' << a[j];
cout << endl;
return ;
}
if (a[n] == n) {
for(int j = n-1; j >= 1; j--) cout << a[j] << ' ';
cout << a[n] << endl;
return ;
}
cout << -1 << endl;
}
int main()
{
int T;
cin >> T;
while(T--) {
work();
}
return 0;
}
D. Weights Assignment For Tree Edges
题目大意:给你一棵树,你需要给树上的边确定一个权值(取值范围是\(1\)~\(10^9\)),使得最后所有结点按照深度排序时,得到一个给定的序列。如果不可行,输出-1。
解题思路:构造法,深度直接定义为0~n-1即可,然后用深搜来判断合法性,最后输出deep[i] - deep[fa[i]]即可。
#include <iostream>
#include <algorithm>
#include <cstring>
#include <string>
#include <queue>
#include <vector>
using namespace std;
int n, rt;
vector <int> y[200005];
int fa[200005], deep[200005], flag;
void dfs(int u) {
if (!flag) return ;
for(int i = 0; i < y[u].size(); i++) {
int v = y[u][i];
if (deep[v] < deep[u]) flag = 0;
else dfs(v);
}
}
void work() {
int a;
cin >> n;
for(int i = 1; i <= n; i++) y[i].clear();
for(int i = 1; i <= n; i++) {
cin >> fa[i];
if (fa[i] == i) rt = i;
else y[fa[i]].push_back(i);
}
for(int i = 1; i <= n; i++) {
cin >> a;
deep[a] = i-1;
}
flag = 1;
dfs(rt);
if (flag == 1) {
for(int i = 1; i <= n; i++) {
cout << deep[i] - deep[fa[i]] << ' ';
}
cout << endl;
}
else {
cout << -1 << endl;
}
}
int main()
{
int T;
cin >> T;
while(T--) {
work();
}
return 0;
}
E1. Escape The Maze (easy version)
感谢温则葆的题解
https://www.luogu.com.cn/blog/Raintime1231/solution-cf1611e1
E2. Escape The Maze (hard version)
感谢温则葆的题解
https://www.luogu.com.cn/blog/Raintime1231/solution-cf1611e2
F. ATM and Students
感谢绍嘉的题解
https://www.luogu.com.cn/blog/101868/solution-cf1611f
G. Robot and Candies
等待郑和易的题解
<

浙公网安备 33010602011771号