专栏文章

题解:CF803D Magazine Ad

CF803D题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mipafcnc
此快照首次捕获于
2025/12/03 08:47
3 个月前
此快照最后确认于
2025/12/03 08:47
3 个月前
查看原文

题意

这道题是在满足行数限制的条件下,找到广告所需的最小宽度。确定每行可容纳的最大字符数,通过 二分查找 来优化这个过程。

思路

  • 将给定的广告划分为不超过 kk 行,找到最小的可能宽度,使得所有行的长度都不超过这个宽度。
  • 用二分来确定最小宽度。对于每个宽度,检查是否可行。
  • 对于每个宽度,模拟划分过程,统计行数。如果行数不超过 kk,则可行。

代码

CPP
#include<bits/stdc++.h>
using namespace std;
const int MAXN = 1e6 + 5;
int a[MAXN];
bool fun(int ll, int width, int k) {
    int lines = 1;
    int len = 0;
    for (int i = 0; i < ll - 1; ++i) {
        int S = a[i + 1] - a[i];
        if (S > width) {
            return false;  //长度超过宽度,不可行
        }
        if (len + S <= width) {
            len += S;
        } else {
            ++lines;
            len = S;
        }
        if (lines > k) {
            return false;  //行数超过限制,不可行
        }
    }
    return true;  //所有条件满足,可行
}

int main() {
    int k;
    cin >> k;
    cin.ignore();
    string ad;
    getline(cin, ad);
    
    int LL = 0;
    
    a[LL++] = -1;  // 起始位置
    
    for (int i = 0; i < ad.length(); ++i) {
        if (ad[i] == ' ' || ad[i] == '-') {
            a[LL++] = i;
        }
    }
    a[LL++] = ad.length() - 1;  // 结束位置
    
    int l = 1;
    int r = ad.length();
    int ans = ad.length();
    
    while (l <= r) {
        int mid = (l + r) / 2;
        
        if (fun(LL, mid, k)) {
            ans = mid;
            r = mid - 1;
        } else {
            l = mid + 1;
        }
    }
    
    cout << ans << endl;
    return 0;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...