Codeforces Round #669 (Div. 2)
A
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
const int N = 1e3 + 5;
int n, m, _, k;
int a[1005];
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n;
int x = 0, y = (n + 1) / 2, z = 0;
rep (i, 1, n) {
cin >> a[i];
x += a[i];
}
if (x <= y) {
n -= x;
cout << n << '\n';
rep (i, 1, n) cout << "0 ";
cout << '\n';
} else if (n - x <= y) {
n = x; if (n & 1) --n;
cout << n << '\n';
rep (i, 1, n) cout << "1 ";
cout << '\n';
}
}
return 0;
}
B
贪心, 最大值肯定在 1, 然后就是枚举下一个数 使得当前 __gcd(cur_gcd, a[j]) 最大
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
const int N = 1e4 + 5;
int n, m, _, k, x, y;
int main() {
IOS;
for (cin >> _; _; --_) {
cin >> n;
VI a(n), b(n), v(n, 0);
for (auto &i : a) cin >> i;
sort(all(a), greater<int>());
int cur = b[0] = a[0]; v[0] = 1;
rep (i, 1, n - 1) {
int res = 0, w;
rep (j, 1, n - 1)
if (!v[j]) {
int c = __gcd(cur, a[j]);
if (res < c) res = c, w = j;
}
cur = res, b[i] = a[w], v[w] = 1;
}
for (auto &i : b) cout << i << ' ';
cout << endl;
}
return 0;
}
C
a % b = x, b % a = y
确定 x < b, y < a
当 a > b, b % a = b = y, a % b = x < b(y),
当 b > a, a % b = a = x, b % a = y < a(x),
说白了, x < y, b = y 且 a > b
y < x, a = x 且 b > a
两两询问, 可以确定一个数的值. 且维护着 1~i 的最大值的位置
知道遍历完, 你得到了 1~n 最大值的位置, 其他的数在两两比较中, 已经知道值
最大值== n
#include <bits/stdc++.h>
#define all(n) (n).begin(), (n).end()
#define se second
#define fi first
#define pb push_back
#define mp make_pair
#define sqr(n) (n)*(n)
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define IOS ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(nullptr)
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> PII;
typedef pair<ll, ll> PLL;
typedef vector<int> VI;
typedef double db;
const int N = 1e4 + 5;
int n, m, _, k, x, y;
int a[N];
int h[N], ne[N], to[N], co[N], tot;
void add(int u, int v, int c) {
ne[++tot] = h[u]; to[h[u] = tot] = v; co[tot] = c;
}
int main() {
IOS; cin >> n;
int mx = 1;
rep (i, 2, n) {
cout << "? " << mx << ' ' << i << '\n';
cout.flush(); cin >> x;
cout << "? " << i << ' ' << mx << '\n';
cout.flush(); cin >> y;
if (x > y) a[mx] = x, mx = i;
else a[i] = y;
}
a[mx] = n;
cout << "! ";
rep (i, 1, n) cout << a[i] << ' ';
cout.flush();
return 0;
}
D
单调栈(主要)代码如下
std::vector<int> dp(n, n);
dp[0] = 0;
std::vector<int> s{0}, p{0};
for (int i = 1; i < n; ++i) {
dp[i] = std::min(dp[i - 1], dp[i - 1]) + 1;
while (!s.empty() && h[i] >= h[s.back()]) {
int x = h[s.back()];
s.pop_back();
if (h[i] > x && !s.empty())
dp[i] = std::min(dp[i], dp[s.back()] + 1);
}
while (!p.empty() && h[i] <= h[p.back()]) {
int x = h[p.back()];
p.pop_back();
if (h[i] < x && !p.empty())
dp[i] = std::min(dp[i], dp[p.back()] + 1);
}
s.push_back(i);
p.push_back(i);
}
std::cout << dp[n - 1] << "\n";