首页 > 其他分享 >2024信友队蓝润暑期集训提高1班②Day1

2024信友队蓝润暑期集训提高1班②Day1

时间:2024-07-16 15:58:50浏览次数:11  
标签:10 甜筒 int Day1 2024 蓝润 大臣 te lld

知识总结

原理:

每一步都采取局部最优解,取到最终的最优解。

常见时间复杂度

$ O(n)$ 或 $O(nlog (n))$
后者一般带排序。

用法:

  1. 通过数据规模和题目信息联想贪心算法常见时间复杂度

  2. 猜测结论

  3. 验证合理性
    ​ - 归纳法
    ​ - 反证法(相邻交换法):如果交换方案中相邻的两个元素/任意的两个元素后,答案不会变得更好,那么可以推定目前的解已经是最优解了。

后悔解法

无论当前的选项是否最优都接受,然后进行比较,如果选择之后不是最优了,则反悔,舍弃掉这个选项;否则,正式接受。

(这种算法支持对过往操作的“反悔”,但要求支持的反悔信息和本身贪心的结构是相同的)

考场技巧

1.尝试测试手模样例,并和暴力对拍。

2.多写几个贪心拼凑出最优解。

3.有榜时观察其他人的过题速度,若大家都过不去同一题,先跳过或选择拿暴力等部分分。

随堂练习

T1 小信吃甜筒

题目描述

小信想吃到 $n$ 个巧克力味的甜筒和 $m$ 个草莓味的甜筒,不能多吃。

冰柜里,有 $x$ 个巧克力味甜筒,饱食度分别为 $a_1, a_2,...,a_x$ ,有 $y$ 个草莓甜筒,饱食度分别为 $b_1, b_2,...,b_y$ ,有 $z$ 个原味甜筒,饱食度分别为 $c_1, c_2,...,c_z$ 。小信可以在原味甜筒上加调味料使其变成巧克力味或草莓味。

他想知道在不多吃的情况下能获得的最大饱食值。

思路解析

由于不能多吃,所以我们可以先把原味甜筒加入,然后再取吃巧克力味甜筒和草莓味甜筒其中分别较大的。
然后直接排序选入后的数列,选取 $n+m$ 个最大的数,即可得到最大饱食值。

代码实现

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n, m, l, x, y, z, a[N], b[N], c[N], v[N], flag, ans, ans1;
bool cmp1(int A, int B) {
    return A > B;
}
signed main() {
    scanf("%lld %lld %lld %lld %lld", &n, &m, &x, &y, &z);
    for (int i = 1; i <= x; i++) {
        scanf("%lld", &a[i]);
    }
    for (int i = 1; i <= y; i++) {
        scanf("%lld", &b[i]);
    }
    for (int i = 1; i <= z; i++) {
        scanf("%lld", &c[i]);
        v[i] = c[i];
    }
    sort(a + 1, a + 1 + x, cmp1);
    sort(b + 1, b + 1 + y, cmp1);
    for (int i = 1; i <= n; i++) {
        v[i + z] = a[i];
    }
    for (int i = 1; i <= m; i++) {
        v[i + z + n] = b[i];
    }
    sort(v + 1, v + 1 + n + m + z, cmp1);
    for (int i = 1; i <= n + m; i++) {
        ans += v[i];
    }
    printf("%lld", ans);
    return 0;
}

T2 替换字母 2

双倍经验: https://www.luogu.com.cn/problem/P2882

题目描述

有长度为 $n$ 的字符串,仅包含小写字母。小信想把字符串变成只包含一种字母。他每次可以选择一种字符 $c$ ,然后把长度最多为 $m$ 的子串中的字符都替换成 $c$ 。

问小信最少需要多少次操作,才能把字符串变成只包含一种字母?

思路解析

我们可以枚举所有可能的字符 $c$ ,然后计算替换操作次数。
对于每个字符 $c$ ,如果当前符合则跳过,否则替换长度为 $m$ 的子串中的字符。

代码实现

#include <bits/stdc++.h>
using namespace std;
const int inf = 0x3f3f3f3f;
int n, m, ans = inf, cnt;
string a;
int found(char x) {
    cnt = 0;
    for (int i = 0; i < n;) {
        if (a[i] == x) {
            i++;
        } else {
            cnt++;
            i += m;
        }
    }
    return cnt;
}
int main() {
    cin >> n >> m >> a;
    for (char i = 'a'; i <= 'z'; i++) {
        ans = min(ans, found(i));
    }
    printf("%d\n", ans);
    return 0;
}

T3 异或与乘积

题目描述

有 $n$ 个数你可以将两个数字异或,最终将所有数字相乘,问总乘积最大是多少

由于答案可能很大,输出对 $1 000 000 007$ 取模后的结果。

思路解析

  • 分离出 1 的位置:首先,我们可以找出所有数中为 1 的位,并将这些数分离出来。这些数在异或运算中起到关键作用。
  • 处理偶数的情况:偶数 $\oplus$ $1$ = 偶数 $+$ $1$,奇数 $\oplus$ $1$ $=$ 奇数 $-$ $1$因此利用和一定,差小积大:在分组时,我们希望两组的异或结果尽可能接近,这样它们的差值就会小,根据乘法的性质,差值小的两个数相乘会得到更大的乘积。
  • 计算乘积:计算组中所有数的乘积。
  • 最终乘积:将两组的乘积相乘,并取模 $1000000007$ 。

代码实现

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e6 + 10;
int n, cnt1, a[N], ans = 1, mod = 1e9 + 7;
signed main() {
    scanf("%lld", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%lld", &a[i]);
    }
    sort(a + 1, a + 1 + n);
    for (int i = 1; i <= n; i++) {
        if (a[i] == 1) {
            cnt1++;
        }
    }
    for (int i = 1; i <= n; i++) {
        if (!cnt1) {
            break;
        }
        if (!(a[i] & 1)) {
            cnt1--;
            a[i]++;
        }
    }
    for (int i = 1; i <= n; i++) {
        ans = (ans % mod * a[i] % mod) % mod;
    }
    printf("%lld\n", ans);
    return 0;
}

T4 国王游戏

题目描述

恰逢 H 国国庆,国王邀请 $n$ 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 $n$ 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

思路解析

本题数据范围较大,因此我们需要使用高精度算法来解决。

对于每一个大臣,他的贡献值就是前面所有大臣的左手的贡献值除以他的右手的贡献值。

如果我们用反证法来验证合理性,那么我们可以找到如果任意交换两个大臣都会使答案更劣,那么我们就证明了答案是最优的。
那么对于每两个大臣,如果将这两个单独处理,则前面大臣的贡献值设为 $x$
则如果将大臣 A 放在大臣 B 前面的贡献值就是 $x·a.l·b.l/b.r$
则如果将大臣 B 放在大臣 A 前面的贡献值就是 $x·b.l·a.l/a.r$
比较这两个贡献值,我们可以得到一个不等式:
若将大臣 A 放在大臣 B 前面贡献值更优,则有 $a.l/b.r<b.l/a.r$ ,化简为 $a.l·a.r<b.l·b.r$

代码实现

#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 1e4 + 10;
struct node {
    int l, r;
} q[N];
int n, x, y, cina, cinb;
vector<int> a, b;
bool cmp(node A, node B) {
    return A.l * A.r < B.l * B.r;
}
namespace High {
void gjc(int x) {
    vector<int> te;
    int temp = 0;
    for (int i = 0; i < a.size(); i++) {
        temp += (a[i] * x);
        te.push_back(temp % 10);
        temp /= 10;
    }
    while (temp > 0) {
        te.push_back(temp % 10);
        temp /= 10;
    }
    a = te;
}
void gjch(int x) {
    vector<int> te;
    int r = 0;
    for (int i = a.size() - 1; i >= 0; i--) {
        r = r * 10 + a[i];
        te.push_back(r / x);
        r %= x;
    }
    reverse(te.begin(), te.end());
    while (!te.empty() && te.back() == 0) {
        te.pop_back();
    }
    if (te.size() > b.size())
        b = te;
    if (!te.empty() && te.size() == b.size()) {
        for (int i = te.size() - 1; i >= 0; i--) {
            if (te[i] > b[i]) {
                b = te;
                break;
            } else if (te[i] == b[i])
                continue;
            else if (te[i] < b[i])
                break;
        }
    }
}
}  // namespace High
using namespace High;
signed main() {
    scanf("%lld", &n);
    scanf("%lld %lld", &x, &y);
    for (int i = 1; i <= n; i++) {
        scanf("%lld %lld", &cina, &cinb);
        q[i].l = cina;
        q[i].r = cinb;
    }
    sort(q + 1, q + 1 + n, cmp);
    while (x) {
        a.push_back(x % 10);
        x /= 10;
    }
    for (int i = 1; i <= n; i++) {
        gjch(q[i].r);
        gjc(q[i].l);
    }
    if (!b.empty()) {
        for (int i = b.size() - 1; i >= 0; i--) {
            printf("%lld", b[i]);
        }
    } else {
        printf("0");
    }
    return 0;
}

课后作业

待更
//TODO

标签:10,甜筒,int,Day1,2024,蓝润,大臣,te,lld
From: https://www.cnblogs.com/TangyixiaoQAQ/p/18290668

相关文章

  • 2024信友队蓝润暑期集训提高1班②Day0
    前言去年参加了杭师大的暑期集训,那时候还是普及1班①的小萌新,转眼间,现在已经在读提高组的知识了。这一次的安吉似乎景色更加优美。9:30从绍兴出发12:00到达安吉13:00吃中饭14:00在教室刷题、打比赛(当然也有部分时间在摸鱼)18:00吃晚饭19:00去大报告厅看开营仪式。......
  • 2024信友队蓝润暑期集训提高1班②Day3
    前言noip毒瘤给我们讲上午的知识知识总结题目T1【模板】单调栈题目描述题目描述:给出项数为n的整数数列a1…n,定义函数f(i)代表数列中第i个元素之后第一个大于ai的元素的下标,即f(i)=mini<j<=n,aj>ai{j}。若不存在,则f(i)=0。试求出f(1…n)。输入格式:第一行......
  • 2024信友队蓝润暑期集训提高1班②Day2
    知识总结转化、构造、模拟。转化:将算法转化为其他形式。构造:通过算法构造一个模型。模拟:通过算法模拟一个过程。随堂练习T1排行榜题目描述https://www.luogu.com.cn/problem/P1159思路解析显然这题可以直接贪心。把一首一首歌往排行榜上放。对于SAME的歌,直接放在原......
  • 2024信友队蓝润暑期集训提高1班②Day5
    知识总结最小生成树最小生成树的定义:在一个无向连通图中,找出权值最小的生成树,使得生成树中任意两个顶点间都有且仅有一条路径。最小生成树的性质:无向连通图的最小生成树是唯一的。最小生成树的权值是图中所有边的权值的最小值。最小生成树的边数等于图的顶点数减一。最小......
  • 2024信友队蓝润暑期集训提高1班②Day4
    知识总结搜索算法剪枝剪枝是指在搜索树的构造过程中,对某些分支不必继续探索,从而减少搜索树的大小,提高搜索效率。启发式搜索启发式搜索是指根据某种启发式函数对搜索树进行排序,使得搜索树中优先扩展那些有可能产生最优解的分支。迭代加深搜索迭代加深搜索是指在搜索树的构造......
  • [2024] springboot Hadoop技术下的校园二手交易系统的设计与实现
    博主介绍:✌CSDN新星计划导师、Java领域优质创作者、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HTML、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app、大数......
  • 2024最新版Python安装详细教程!一键安装,永久使用
    打开上面的Python官网地址,如下图所示,鼠标放入网页Downloads栏目,选择里面的windows操作系统。三、进入windows对应的页面,选择python版本(1)选择python的稳定发布版本StableReleases点击进入windows操作系统对应的页面,显示python安装版本,这些python安装版本适合windows操......
  • 2024-07-16 代码高亮插件highlight.js安装使用以及排错日志
    highlight.js—— 一个开源语法高亮库,用于在网页上对源代码进行语法高亮显示。安装npmihighlight.jsyarnaddhighlight.js引入//main.jsimport{createApp}from'vue';importAppfrom"./App.vue";importhljsfrom"highlight.js";//代码高亮插件import......
  • SMU Summer 2024 Contest Round 4
    SMUSummer2024ContestRound4MadeUp题意给你三个序列\(A,B,C\),问你满足\(A_i=B_{C_j}\)的\((i,j)\)对有多少。思路由于\(1\leA_i,B_i,C_i\leN\),所以可以统计\(Cnt[A_i]\)和\(Cnt[B_{C_i}]\)的个数,两者相乘累加即可。代码#include<bits/stdc++.h>using......
  • 2024-07-16 记录vue内置组件(ps:内容来自GPT)
    1. Transition和TransitionGroup用途:用于为单个元素或组件提供过渡效果。TransitionGroup则用于列表中的多个元素或组件的过渡效果。特点:Transition:只影响单个元素或组件,不会额外渲染DOM元素。TransitionGroup:渲染一个真实的DOM元素(默认为<span>),可以通过tag属性改变渲染......