2023.6.22 每日一题

原题链接

A: COMPFEST 13 - Finals Online Mirror (Unrated, ICPC Rules, Teams Preferred) - K

B: Educational Codeforces Round 125 (Rated for Div. 2) - D

A. Knitting Batik - 2200

题目大意

给一个 \(n\times m\) 的矩形,可以给这些方格染 \(k\) 种颜色,问有多少染色方式使得两个给定区域内图案相同。

解题思路

如果两个矩形一样答案一定是 \(k^{nm}\),如果部分重叠,那么就是去掉一个矩形后的确定方式,幂指数减去 \(rc\) 即可。

AC Code

#include <iostream>
#include <algorithm>
#include <cstring>
#define endl '\n'
#define ios ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr)
using namespace std;
typedef long long LL;

const int N = 4e5 + 10;
const int MOD = 1e9 + 7;

int qmi(LL a, LL k) {
    int res = 1;
    while (k) {
        if (k & 1) res = (LL) res * a % MOD;
        a = (LL) a * a % MOD;
        k >>= 1;
    }
    return res;
}

void solve() {
    LL n, m, k, r, c;
    cin >> n >> m >> k >> r >> c;
    int a, b, e, d;
    cin >> a >> b >> e >> d;
    cout << qmi(k, n * m - (a - e || b - d) * r * c) << endl;
}

signed main() {
    ios;
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}

B. For Gamers. By Gamers - 2000

题目大意

在进行一场游戏,需要击败 \(m\) 头怪物,第 \(i\) 只的血量为 \(H_i\),攻击力为 \(D_i\)

起初有 \(c\) 个金币,每一场战斗前都会有 \(c\) 个金币去招募士兵,有 \(n\) 种士兵可以招募,每种士兵的血量为 \(h_i\),攻击力为 \(d_i\),需要花费 \(c_i\) 个金币。

我们不能使士兵死亡, 每个同时招募的士兵要是同一种类型的。

如果能战胜怪物当且仅当怪物战士一个士兵的时间大于士兵们战胜怪物的时间。

击败时间计算方式为敌方血量除以己方攻击力。

现在想知道杀死每只怪物至少要多少金币,如果比起始金币数量大就输出 \(-1\)

解题思路

我们先对士兵按照 \(d\times h\) 取最优排序,然后比较每个士兵需要的 \(c\),二分找最小的总金币数,判断与初始值的大小关系即可。

AC Code

#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
#define endl '\n'
#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;

const int N = 1e6 + 10;
const int MOD = 1e9 + 7;

LL a[N], d[N], h[N];
LL cnt[N], max_[N];

void solve() {
    int n, c, m;
    cin >> n >> c;
    for (int i = 0; i < n; i++) {
        cin >> a[i] >> d[i] >> h[i];
        cnt[a[i]] = max(cnt[a[i]], d[i] * h[i]);
    }
    for (int i = 1; i <= c; i++) {
        for (int j = i; j <= c; j += i) {
            max_[j] = max(max_[j], (j / i) * cnt[i] - 1);
        }
    }
    for (int j = 1; j <= c; j++) {
        max_[j] = max(max_[j], max_[j - 1]);
    }
    cin >> m;
    for (int i = 0; i < m; i++) {
        LL D, H;
        cin >> D >> H;
        LL v = D * H;
        LL res = lower_bound(max_, max_ + c + 1, v) - max_;
        cout << (res > c ? -1 : res) << ' ';
    }
}

signed main() {
    ios;
    int T = 1;
//    cin >> T;
    while (T--) {
        solve();
    }
}
posted @ 2023-06-23 00:18  叁纔  阅读(17)  评论(0编辑  收藏  举报