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

正解单调栈处理, 不过看rk1, 有个有意思的方法

单调栈(主要)代码如下

    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";
posted @ 2020-09-09 14:29  洛绫璃  阅读(165)  评论(0编辑  收藏  举报