Codeforces Round #656 (Div. 3)
A. Three Pairwise Maximums
题意:对于每组测试样例给出三个数x y z,你需要寻找三个数a, b, c使得x = max(a,b) y = max(a,c) z = max(b,c) 如果能找到则输出YES按任意顺序打印abc
题解:因为z是a、b和c三个整数中的最大值,并且它以两对出现(因此它在x、y和z中最多出现两次)。否则,答案就存在了,它可以是x,x和z,
代码:
#include <iostream>
using namespace std;
int main() {
int t, x ,y ,z;
cin >> t;
while(t--) {
bool Ture = false;
int a = 0;
int b = 0;
int c = 0;
cin >> x >> y >> z;
if(x == y && y == z) {
Ture = true;
a = x;
b = x;
c = x;
} else if(x == y && z < x) {
Ture = true;
a = x;
b = z;
c = z;
} else if(x == z && y < x) {
Ture = true;
b = x;
a = y;
c = y;
} else if(z == y && x < z) {
Ture = true;
c = z;
b = x;
a = x;
}
if(Ture) {
cout << "YES" << endl;
cout << a << " " << b << " " << c << endl;
} else
cout << "NO" << endl;
}
return 0;
}
B. Restore the Permutation by Merger
题意:给出一个merge后的序列,求出以前的序列。
题解:遍历
代码:
#include <iostream>
#include <cstring>
using namespace std;
int a[55];
int b[150];
int num[55] = {0};
int main() {
int t, n;
cin >> t;
while(t--) {
memset(num,0,sizeof(num));
int ans = 1;
cin >> n;
for(int i = 1; i <= 2*n; i++) {
cin >> b[i];
if(num[b[i]] == 0) {
a[ans] = b[i];
ans++;
num[b[i]]++;
}
}
for(int i = 1; i <= n; i++)
cout << a[i] << " ";
cout << endl;
}
}
C - Make It Good
题意: 给出一个长度为n的序列,问你删除最少的前缀,使其变为一个good序列。所谓good序列是指通过删除a序列的头部或尾部添加到c序列,使得c序列单调不减。
代码
#include <iostream>
using namespace std;
int a[200005];
int main() {
int t, n;
cin >> t;
while(t--) {
cin >> n;
for(int i = 1; i <= n; i++) {
cin >> a[i];
}
int head = 1;
int tail = n;
for(int i = n; i >= 1; i--) {
if(a[i] > a[i-1]) {
tail = i-1;
break;
}
}
for(int i = tail; i >= 1; --i) {
if(a[i] < a[i-1]) {
head = i;
break;
}
}
cout << head - 1 << endl;
}
}
D - a-Good String
题解:二分
代码:
#include <iostream>
#include <cmath>
#include <cstdio>
using namespace std;
char a[200005];
int solve(int l, int r, char c) {
if(l == r)
return a[l] != c;
int mid = (l+r)/2;
int left = 0;
int right = 0;
for(int i = l; i <= mid; i++) {
if(a[i] != c)
left++;
}
for(int i = mid + 1; i <= r; i++) {
if(a[i] != c)
right++;
}
return min(left + solve(mid+1,r,c+1),right+solve(l,mid,c+1));
}
int main() {
int t, n;
cin >> t;
while(t--) {
cin >> n;
scanf("%s", a + 1);
cout << solve(1,n,'a') << endl;
}
return 0;
}
E - Directing Edges
题意:给你一个图,告诉你的边有点是有向的有些是无向的,把无向的边变成有向,如果形成的新的图有环,输出NO,否则输出YES。
题解:
先引入一个新的概念:拓扑排序详解
先建造一个只有有向边的拓扑排序。检查这些有向边组成的图中是否含有环。然后给无向边加方向只需要按照拓扑序顺序加方向即能保证不会出现环。