洛谷 2 月月赛 I & 『MdOI R4』 (Div2) A ~ D 四题全,也许会有六题,超高质量题解 (Div.1E、F下辈子一定补)【每日亿题2 / 9】

这篇博客分享了洛谷2月月赛中A到D四题的详细解题思路,包括"Fun"、"Color"、"Kotori"和"Balance"。涉及的算法包括简单的模拟、贪心策略、可并堆和分数规划,适合算法学习和模板整理。
摘要由CSDN通过智能技术生成

整理的算法模板合集: ACM模板

点我看算法全家桶系列!!!

实际上是一个全新的精炼模板整合计划


这场月赛就离谱

Div1,一千多人参加,除了两位大佬两题以外,其他人最多一题…
C题可并堆,D题分数规划,E题PQ树,F题生成函数NTT,离谱

A、P7337 『MdOI R4』Fun

Problem A. Fun

VG 的学校有 n n n 个人要去考 NOIP。

每个人有一个交通方式,第 i i i 个人的交通方式为 t i t_i ti t i = 1 t_i=1 ti=1表示这个人坐学校大巴, t i = 0 t_i=0 ti=0 表示这个人自己去考场。

每个人有一个颓废值,第 i i i 个人的颓废值为 q i q_i qi q i = 1 q_i=1 qi=1表示这个人愿意打狼, q i = 0 q_i=0 qi=0 表示这个人不愿意打狼。

每个人去考场时会买一瓶快乐水,但如果坐大巴且愿意打狼的人数(即满足 t i = 1 t_i=1 ti=1 q i = 1 q_i=1 qi=1 i i i 个数) k k k 不小于 m m m ,则这 k k k 个人只需要买 m m m 瓶快乐水。

现在,VG 统计出了所有人的交通方式和颓废值,他希望请求你帮他求出最终所有人买快乐水的总瓶数。

Soluiotn

签到题,读懂题意直接模拟就行了(我看到题还楞了一下,怎么这么简单???

可能是因为数据太少,我用快读快输还没有直接scanf跑的快…

时间复杂度: O ( n ) O(n) O(n)
Code

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>

using namespace std;

const int N = 5007;

int n, m;
int t[N], q[N];
int type;

int main()
{
   
    scanf("%d%d%d", &n, &m, &type);
    for(int i = 1; i <= n; ++ i) {
   
        scanf("%d", &t[i]);
    }
    for(int i = 1; i <= n; ++ i) {
   
        scanf("%d", &q[i]);
    }
    int k = 0;
    for(int i = 1; i <= n; ++ i) {
   
        if(t[i] && q[i]) {
   
            k ++ ;
        }
    }
    int ans = n - k;
    if(k >= m) {
   
        ans += m;
    }
    else ans += k;
    printf("%d\n", ans);
    return 0;
}

B、P7338 『MdOI R4』Color

Problem B. Color

小 M 同学有一张 2 2 2 n n n 列的方格纸,一开始所有格子都是白色的。

她决定对一些格子染色,具体地,每次她会选择两个相邻的(四联通的,也就是有公共边的)白色格子,其中一个染成红色,另一个染成蓝色。

她的目标是通过任意次操作让指定的一些格子变成红色,对其他格子没有要求。请你帮她判断一下,能否通过上述操作达成目标呢?

Soluiotn

简单画图模拟以后,直接贪心即可。

我直接乱搞疯狂分类讨论疯狂贪心然后就过了…因为只有两行,所以情况不会太多 ~

好吧我这个思路其实就是正解。

不过我见过有人用Dinic满分来着hhh
还有用匈牙利跑二分图匹配99分的hhh

简单讲一下思路:题目要求每次染色的时候必须选择两个白色格子,也就是只能选择没有染过色的格子,然后给我们一个期望染色的方案,并且没有标 1 是 0 的格子的颜色是不做要求的。

所以我们就可以直接根据它给定的期望方案去染色,对于每一个1来说,因为只有两行,所以我们分类讨论(若有 n n n m m m 列就是经典的网络流最大匹配了 ~ )

根据题意只有相邻的才能选上一块染色,所以我们只需要考虑每个1的上下左右,也就是上下行和前后列,优先考虑前面一列,然后考虑上下以及后面的只有一个0的情况,若没有0直接 NO ,剩下最后一种情况就是下和后,或者上和后都可以选,我们优先考虑下或者上,也就是同一列的那个格子,因为同一列第 i i i 列的格子,之后 第 i + 1 i+1 i+1 列可以用到,而后一列即第 i + 1 i+1 i+1 的那个可选的格子, 第 i + 2 i+2 i+2 列也可以使用 ~ 然后我们模拟的时候染成红色的时候就置为 1 ,蓝色就置为 2 ,然后就没了

时间复杂度: O ( n ) O(n) O(n)

Code

然后就是我10分钟一通乱搞AC的丑陋的代码了 ~

#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <map>
#include <vector>
#include <unordered_map>
#define x first
#define y second
using namespace std;
typedef long long ll;
typedef pair<ll, ll> PLL;
typedef int itn;
const int N = 5e5 + 7, M = 1e6 + 7, mod = 1e9 + 7;
const ll INF = 1e18 + 7;
ll n, m, t;
ll A, B;
string a, b;

bool solve()
{
   
    scanf("%d", &n);
    cin >> a >> b;
    for(int i = 0; i < n; ++ i) {
   
        bool flag1 = 0, flag2 = 0;
        if(a[i] == '1') flag1 = 1;
        if(b[i] == '1') flag2 = 1;
        if(flag1) {
   
            if(i != 0 && a[i - 1] == '0') {
   
                a[i - 1] = 
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

繁凡さん

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值