HideCharSkinCapInfo

备战传智蓝桥DAY-13

🕒 学习与练习计划

⏰ 时间段📘 内容
13:30-18:40📝 复习二分
20:20-22:30📝 复习二分

完成情况


💡 解题思路与总结

题目1.愤怒的牛

  • 解题方法:二分对答案
  • 解决方案
angry_cows.cpp
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e3 + 10;
 
int n, c;
vector<int> loc;
void solve() {
    cin >> n >> c;
    loc.resize(n);
    for (int i = 0; i < n; i ++) cin >> loc[i];
 
    sort(all(loc));
 
    auto check = [](int d) {
            int cnt = 1 , st = loc[0];
            for (int j = 1; j < loc.size(); j ++) {
                if (loc[j] - st >= d) {
                    cnt ++;
                    st = loc[j];
                    if(cnt >= c) return true;
                }
        }
        return false;
    };
 
    int l = 0, r = INF;
    while (l < r) {
        int mid = l + r + 1 >> 1;
        if (check(mid)) l = mid;
        else r = mid - 1;
    }
 
    cout << l;
}
 
signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}
 
/**
 *    author: Nijika_jia
 *    created: 2025.02.22 13:40:47
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目2.Best Cow Fences

  • 解题方法:二分答案 , 每个区间和都减去平均值,如果区间的和还大于0说明该区间的平均值大于当前平均值
  • 遇到的问题:用单调队列会超时
  • 解决方案
best_cow_fences.cpp
cpp
#include <bits/stdc++.h>
// #define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e3 + 10;

int n, len;
int ans;
int a[N];
double sum[N];
bool check(double avg) {
     for (int i = 1; i <= n; i ++) sum[i] = sum[i - 1] + a[i] - avg;
     double minn = 1e10;
     for (int i = 0 , j = len; j <= n; i ++, j++) {
        minn = min(minn, sum[i]);
        if (sum[j] >= minn) return true;
     }
     return false;
}
void solve() {
    cin >> n >> len;
    for (int i = 1; i <= n; i ++) cin >> a[i];

    double l = 0, r = 1e5;
    while (abs(l - r) > 1e-6) {
        double mid = (l + r) / 2;
        if (check(mid)) l = mid;
        else r = mid;
    }

    printf("%d",(int)(r*1000));
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.22 14:03:36
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目3.数列分段II

  • 解题方法:二分答案
  • 遇到的问题:不知道为啥l和r的值不能设成常用的0和INF,必须l是数列最大值,r是数列和
  • 解决方案
divide_sequence.cpp
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e3 + 10;

int n, m;
int a[N];
bool check(int limt) {
    int cnt = 0, sum = 0;
    for (int i = 0; i < n; i ++) {
        if (sum + a[i] > limt) {
            sum = a[i];
            cnt ++;
        }else sum += a[i];
    }
    cnt ++;
    if (cnt > m) return false;
    return true;
}
void solve() {
    cin >> n >> m;
    int l = 0, r = 0;
    for (int i = 0; i < n; i ++) cin >> a[i],l = max(l,a[i]), r += a[i];

    while (l < r) {
        int mid = l + r >> 1;
        if (!check(mid)) l = mid + 1;
        else r = mid;
    }

    cout << l;
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.22 15:44:06
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目4.工厂质检员

  • 解题方法:二分答案,这次是l+r+1>>1
  • 解决方案
quality_inspector.cpp
cpp
#include <bits/stdc++.h>
#define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e3 + 10;

int n, k;
int h[N];
bool check(int limt) {
    int cnt = 0;
    for (int i = 0; i < n; i ++) {
        cnt += h[i] / limt;
    }
    return cnt < k;
}
void solve() {
    cin >> n >> k;
    for (int i = 0; i < n; i ++) cin >> h[i];
    int l = 0, r = INF;
    while (l < r) {
        int mid = l + r + 1 >> 1;
        if (check(mid)) r = mid - 1;
        else l = mid;
    }
    cout << (l == 0 ? -1 : l) << '\n';
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.22 16:59:33
 *    description: C++20 Algorithm Template for Competitive Programming
 */

题目5.肖恩的n次根

  • 解题方法
  • 遇到的问题

🔬 关键点:int() vs cout

代码计算结果(假设有浮点误差)实际输出
int(l * 1000)int(293999.99999999)293999 (直接截断)
cout << (l * 1000);294000.0294000 (默认格式保留精度)
  • 解决方案
nth_root.cpp
cpp
#include <bits/stdc++.h>
// #define int long long // 仅在需要大整数时使用,memset 数组为 0x3f 时去掉
#define INF 0x3f3f3f3f
#define PII pair<int, int>
#define ULL unsigned long long
#define PIII tuple<int, int, int>
#define all(v) v.begin(), v.end()
#define debug(a) cout << #a << " = " << a << endl;
using namespace std;
constexpr int N = 1 * 1e6 + 10, M = 5 * 1e3 + 10;


void solve() {
    int a, b;
    cin >> a >> b;
    if (b == 1) {
        cout << a * 1000;
        return;
    }
    double l = 0, r = 1e18;
    while (abs(l - r) > 1e-11) {
        double mid = (l + r) / 2;
        if(pow(mid, b) <= a) l = mid;
        else r = mid;
    }

    cout << int(l * 1000);
}

signed main() {
    ios::sync_with_stdio(0); cin.tie(nullptr), cout.tie(nullptr);
    int _ = 1;
    // cin >> _;
    while (_--) {
        solve();
    }
    return 0;
}

/**
 *    author: Nijika_jia
 *    created: 2025.02.22 20:26:30
 *    description: C++20 Algorithm Template for Competitive Programming
 */

额外收获:


🔧 改进计划

  • 针对今日问题:
    • 📖 复习:复习二分感觉没啥难度
    • 📊 刷题:二分的题总体还是套路多
    • 时间管理:仍然是晚睡晚起

📖 明日计划

  • 💻 暂时不知道,大概是学新东西

📝 附注

🍕封面图


Q.E.D.
头歌包过教程(对付给看输出的那种实验)
Valaxy v0.28.11 驱动|主题-Yunv0.28.11
本站总访问量
本站访客数 人次
本站已运行0 天0 小时0 分0 秒