赛氪3.14

赛氪3.14题解

A,B,M,I是签到题目

(but我B题看走眼,多交了好几发,对我自己无语了

重点是理一下F题的模拟

J题目 奇怪的小鸭子也增加了

题意

有一个A×B 的大澡盆,还有若干个a×b 的长方形小鸭子,澡盆里最少放几只鸭子后,便无法再向其中放入更多的鸭子?

鸭子很倔强,不能旋转成 b×a ,也不能重叠放置。

题解

一开始我以为,小鸭子只能放在线上,实际上不是的

原 来 的 设 想 是 放 在 线 上 , 那 么 一 个 小 鸭 子 可 以 使 得 长 ( ( a − 1 ) ∗ 2 + a ) , \color{orange}原来的设想是放在线上,那么一个小鸭子可以使得长((a - 1) * 2 + a), 线使((a1)2+a)
宽 ( ( b − 1 ) ∗ 2 + b ) 不 能 放 鸭 子 , \color{orange}宽((b - 1) * 2+b)不能放鸭子, ((b1)2+b)
实 际 上 可 以 不 放 在 线 上 , 那 么 就 是 把 一 换 成 精 度 范 围 内 无 限 小 就 好 了 \color{orange}实际上可以不放在线上,那么就是把一换成精度范围内无限小就好了 线

#include <bits/stdc++.h>
typedef long long ll;
using  namespace std;
const int MAX = 2e5 + 10;
const int INF = 1e9;
vector<string> ans;
string res[MAX];
int num[MAX];
const double eps = 1e-12;

int main() {
    int A, B, a, b;
    scanf("%d%d%d%d", &A, &B, &a, &b);
    ll ans = 0;
    A -= (a - eps) * 2 + a;
    B -= (b - eps) * 2 + b;
    ll s = 1, t = 1;
    if(A > 0)
        s += max(0.0, ((A + (2 * a - 2 * eps))/ (2 * a - eps)));
    if(B > 0)
        t += max(0.0, ((B + (2 * b - 2 * eps))/ (2 * b - eps)));
    ans = s * t;
    printf("%lld\n", ans);
}

E题目 神仙爱采药

题意

一个背包体积为V,给出一个字符串s,设长度为n。 则s[i]表示第i天的物品体积,为1或2。第i天可以选择是否将物品i放入背包,若背包容量不够可以先 从中拿出若干物品。 每天结束前在背包中的每个物品会产生一个药丸。 问n天结束后,最多有多少药丸

题解

爆int

#include <bits/stdc++.h>
typedef long long ll;
using  namespace std;
const int MAX = 2e5 + 10;
const int INF = 1e9;
int num[MAX];
const double eps = 1e-12;

int main() {
    int n;
    string str;
    cin >> n >> str;
    ll ans = 0;
    int cnt1 = 0, cnt2 = 0;
    int tot = 0;
    for(int i = 0; i < str.length(); i++) {
        if(str[i] == '1') {
            if(tot + 1 <= n) {
                cnt1++;
                tot++;
            }
            else if(cnt2 >= 1) {
                cnt2--;
                tot--;
                cnt1++;
            }
        }
        else {
            if(tot + 2 <= n) {
                cnt2++;
                tot += 2;
            }
        }
        ans += (cnt1 + cnt2);
    }
    printf("%lld\n", ans);
}

F 题目 但更爱字符串

题意

您是一个神仙,您尤其喜欢字符串。

定义一个好词是第一个字母大写,其他字母均小写且长度大于 1 的单词,例如AkworldfinalOrzorzOrzNb

好串是由好词构成的,两个好词之间有且只有一个空格,且一个好串至少有两个好词。如:International Collegiate Programming Contest

现在您有一篇文章,想让您将其中的好串进行适当的缩写。如:International Collegiate Programming Contest改写为ICPC (International Collegiate Programming Contest)

注意:好串一定是尽可能长的。如International Collegiate Programming Contest能且仅能被唯一地缩写成ICPC (International Collegiate Programming Contest)

题解

注意点:

可能出现一个单词+逗号+好词==》满足

有可能出现末尾有不止一个标点符号==》可能满足

有可能出现一个单词有两个及其以上大写字母==》不满足

有可能出现一个单词只有一个字母,而且是大写字母==》不满足

有可能出现有不止一个空格的情况==》不满足

(每行不超过 128 个字符,总共不会超过 1000行)

可以o(n^2)

呐呐呐,上面这么多情况,几乎都是我在模拟的时候发现的一个又一个tip,这样频繁修改代码,脑子早就糊掉了,所以,不能直接模拟,可以看一下,基本上是满足o(n^2),就可以枚举判断

下 次 模 拟 多 写 函 数 , 方 便 , 模 拟 题 , 先 看 样 例 ( 样 例 提 醒 了 几 个 注 意 点 的 ) \color{red}下次模拟多写函数,方便, 模拟题,先看样例(样例提醒了几个注意点的) 便
太 多 边 界 条 件 了 , 下 次 遇 到 这 种 题 目 , 一 定 要 先 多 想 一 想 , \color{red}太多边界条件了,下次遇到这种题目,一定要先多想一想,
不 要 上 来 就 写 代 码 , 要 改 出 命 来 , 太 变 态 了 \color{red}不要上来就写代码,要改出命来,太变态了

#include <bits/stdc++.h>
typedef long long ll;
using  namespace std;
const int MAX = 2e5 + 10;
const int INF = 1e9;
string str;
string judge(int L, int R) {//截取无标点的区域
    if(!isupper(str[L]) || str[R] == ' ') return "";//首字母是大写而且尾不是空格
    string tmp = "";
    int pos = L;
    for(int i = L; i <= R; i++) {
        tmp += str[i];
        if(str[i] == ' ') {//无连续空格
            pos = i;
            if(str[i - 1] == ' ' && i - 1 >= L) return "";
        }
        if(str[i] == '.' || str[i] == ',' || str[i] == '!') return "";//不包括标点
    }

    pos += 1;//str[pos] = ' '
    int cnt = 0;//截取的最后一个单词不能有两个大写
    while(1) {
        if(!isalpha(str[pos])) break;
        if(isupper(str[pos])) cnt++;
        pos++;
    }
    if(cnt != 1) return "";

    istringstream in(tmp);
    string t;
    string suoxie = "";
    int size = 0;
    while(in >> t) {
        size++;
        int cnt = 1;
        if(!isupper(t[0])) return "";
        suoxie += t[0];
        for(int j = 1; j < t.length(); j++) {
            if(isupper(t[j])) {//有其他的大写字母
                cnt++;
            }
        }
        if(cnt != 1 || t.length() == 1) {//单词有多个大写字母或者为一个字母,不满足
            return "";
        }
    }
    if(size <= 1) return "";//只有一个单词

    string res = "";
    res += suoxie;
    res += " (";
    res += tmp;
    res += ")";
    return res;
}

bool check(int i) {//一个单词不能有两个大写
    int cnt = 0;
    int pos = i;
    while(1) {
        if(!isalpha(str[pos])) break;
        if(isupper(str[pos])) cnt++;
        pos++;
    }
    pos = i - 1;
    while (1) {
        if(!isalpha(str[pos])) break;
        if(isupper(str[pos])) cnt++;
        pos--;
    }
    if(cnt >= 2) return 0;
    if(islower(str[i - 1])) return 0;
    return 1;
}

int main() {
    while(getline(cin, str)) {
        int len = str.length();
        for(int i = 0; i < len; ) {
            string tmp;
            string res = "";
            for(int j = i + 1; j < len; j++) {
                tmp = judge(i, j);
                if(tmp == "") {//不满足
                    continue;
                }
                else res = tmp;
            }
            if(res == "" || !check(i)) {//不满足,或者这个单词有两个极其以上大写字母,或者不是第一个字母大写,前面逗号句号除外
                cout << str[i];
                i++;
            }
            else {
                cout << res;
                int len = res.length() - 3;//减去两个括号以及第一个空格
                for(int i = 0; i < res.length(); i++) {
                    if(isupper(res[i])) len--;
                    else break;
                }
                i += len;
            }
        }
        cout << endl;
    }
}

K题目 关于哥俩好的数字这件事

题意

数字 x,y是个「哥俩好」数字,当且仅当数字 x的数位和与数字 y 的数位和相同。

你需要找 n个不同的正整数,使得这 n个数字两两之间均为「哥俩好」数字且总和最小。

一个整数 n, 1≤n≤5000

最小的「哥俩好」数字总和。

题解

其实数据范围很小,暴力即可

but我没有过,因为我没有看到正整数,也就是1的情况下是1,不是0,啊啊啊

瞎了我的狗眼!!

#include <bits/stdc++.h>
typedef long long ll;
using  namespace std;
const int MAX = 1e7 + 10;
const ll INF = 1e18;
double eps = 1e-12;
vector<int> sum[MAX];

inline void init() {
    for(int i = 0; i <= MAX; i++) {
        int tmp = i;
        int tot = 0;
        while(tmp) {
            tot += tmp % 10;
            tmp /= 10;
        }
        if(sum[tot].size() <= 5010) sum[tot].push_back(i);
    }
}

int main() {
    init();
    int n;
    scanf("%d", &n);
    ll ans = INF;
	if(n == 1) {
      printf("1\n");
    	return 0;
    }
    for(int i = 0; i <= MAX; i++) {
        if(sum[i].size() >= n) {
            ll res = 0;
            for(int j = 0; j < n; j++) {
                res += sum[i][j];
            }
            if(res < ans) {
                ans = res;
            }
        }
    }
    printf("%lld\n", ans);
    return 0;
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值