2024牛客暑期多校训练营5

B - 珑

首先要记得\(a=1\) 短边可以相邻,$b = 1 $ 长边可以相邻。

首先\(n m \equiv 1 \mod2\),一定无解,优先特判这种情况。

\(a = 0, b = 1\)时,可以构造出$3\times 2 k, 2 \times 2 k $,可以用 \(2,3\)拼出任意行,所以只有$1 \times 2 k $ 无解

\(a = 1 , b= 0\) 时,只能排成一排,也就是只有$1\times 2k $ 有解

当$a = 1 , b = 1 $,时,所有情况都合法。

当$a = 0 , b = 0 $ 是,就只有$n = 1 , m = 2 $ 和 $n = 2 , m = 1 $是合法的

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

const i32 inf = INT_MAX / 2;
const i64 INF = LLONG_MAX / 2;

#define int i64

using vi = vector<int>;

void solve() {
    int n, m, a, b;
    cin >> n >> m >> a >> b;
    bool flag = true;
    if (n > m) swap(n, m);

    if ((n * m) % 2 == 1) flag = false;
    if (b == 0 and n != 1) flag = false;
    if (a == 0 and n == 1 and m != 2) flag = false;

    if (flag) cout << "Yes\n";
    else cout << "No\n";
    return;
}

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    for (cin >> T; T; T--)
        solve();
    return 0;
}

E - 安

考虑\(a_i \ne b_i\)的情况

如果\(a_i > b_i\) ,则先手必胜。 因为当\(a_i = b_i\) 时,先手可以立即进行一次操作使得$a_i > b_i \(。因此一定是\)b$先变为0。

在考虑\(a_i = b_i\) 的情况。两个人可以各选择一半变为对自己更优的情况。

#include <bits/stdc++.h>

using namespace std;

using vi = vector<int>;

void solve(){
    int n;
    cin >> n;
    vi a(n), b(n);
    for(int i = 0; i < n; i ++)
        cin >> a[i];
    for(int i = 0; i < n; i ++)
        cin >> b[i];
    int cnt = 0, ans = 0;
    for(int i = 0; i < n; i ++)
        if(a[i] > b[i]) ans ++;
        else if(a[i] == b[i]) cnt ++;
    cout << (cnt + 1) / 2 + ans << "\n";
    return ;
}

int main(){
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int T;
    cin >> T;
    while(T --)
        solve();
    return 0;
}

H - 入

考虑到点数不多,我们可以直接暴搜。

我们可以找到一条最长链,然后链上的点递减,剩下的点赋值为无穷大就好了。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;
using ldb = long double;

const i32 inf = INT_MAX / 2;
const i64 INF = LLONG_MAX / 2;

#define int i64

using vi = vector<int>;

i32 main() {
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int n, m;
    cin >> n >> m;
    vector<vi> e(n + 1);
    vi neighbour(n + 1);
    for (int i = 1; i <= n; i++)
        neighbour[i] |= (1ll << i);

    for (int x, y; m; m--) {
        cin >> x >> y;
        e[x].push_back(y), neighbour[x] |= (1ll << y);
        e[y].push_back(x), neighbour[y] |= (1ll << x);
    }
    int res = 0;
    auto dfs = [&](auto &&dfs, int x, int d, int ban) -> void {
        res = max(res, d);
        for (int y: e[x]) {
            if (ban & (1ll << y)) continue;
            dfs(dfs, y, d + 1, ban | neighbour[x]);
        }
    };
    for (int i = 1; i <= n; i++)
        dfs(dfs, i, 1, 0);
    cout << res;

    return 0;
}

L - 知

可以想到要求是尽可能的平均,且只能从后向前拿。所以如果\(a_i < a_{i+1}\)就执行一次操作。

#include <bits/stdc++.h>

using namespace std;

using i32 = int32_t;
using i64 = long long;

#define int i64
const int mod = 998244353;

using vi = vector<int>;


void solve(){
    int n;
    cin >> n;
    
    vi a(n);
    for(auto &i : a) cin >> i;
    while(true) {
        bool flag = false;
        for(int i = 1; i < n; i ++)
            if(a[i] > a[i-1]) a[i-1] ++, a[i] --, flag = true;
        if(flag) continue;
        else break;
    }
    i64 cnt = 1;
    for(int i : a)
        cnt = cnt * i % mod;
    cout << cnt << "\n";

}
i32 main(){
    ios::sync_with_stdio(false), cin.tie(nullptr);
    int TC;
    cin >> TC;
    while(TC --)
        solve();
    return 0;
}
posted @ 2024-08-21 14:51  PHarr  阅读(6)  评论(0编辑  收藏  举报