Codeforces Round #574 (Div. 2)

Contest Info


Practice Link

SolvedABCD1D2EF
6/7OOOOOØ-
  • O 在比赛中通过
  • Ø 赛后通过
  • ! 尝试了但是失败了
  • - 没有尝试

Solutions


A. Drinks Choosing

题意:
\(n\)个人,每个人喜欢吃第\(k_i\)种糖果,现在商店售卖的糖果是一盒两个的,要买最少数量的盒数,即\(\left\lceil \frac{n}{2} \right\rceil\)盒,并且使得尽量多的人吃上自己喜欢吃的糖果

思路:
将喜欢吃同一种糖果的人放在一起,每次贪心取两个给他们一盒,这样他们的贡献是满的。
剩下的肯定是每种糖果最多只有一个人喜欢吃,那么贡献就是剩余的盒数。

代码:

#include <bits/stdc++.h>
using namespace std;
 
#define N 1010
int n, k, a[N];
 
int main() {
    while (scanf("%d%d", &n, &k) != EOF) {
        memset(a, 0, sizeof a);
        for (int i = 1, x; i <= n; ++i) {
            scanf("%d", &x);
            ++a[x];
        }
        int res = 0;
        int num = n / 2 + (n & 1);
        for (int i = 1; i <= k; ++i) {
            while (a[i] >= 2 && num > 0) {
                --num;
                a[i] -= 2;
                res += 2;
            }
        }
        printf("%d\n", res + num); 
    }
    return 0;
}

B. Sport Mafia

题意:
有两种操作:

  • 如果当前盒子里还有糖果,那么可以去掉一个糖果
  • 放入盒子一些糖果,糖果的数量是上次放入的数量$ + 1$
    问最终给出操作次数\(n\)以及最终盒子里的糖果数量\(k\),问在操作过程中有多少种操作是第一种操作。

思路:
答案显然是\(i \in [1, n]\),并且满足:
\[ \begin{eqnarray*} \frac{i * (i + 1)}{2} - (n - i) = k \end{eqnarray*} \]
相当于求
\[ \begin{eqnarray*} \frac{i^2}{2} + \frac{3i}{2} - n - k = 0 \end{eqnarray*} \]
的方程的根。
显然该二次方程的对称轴在\(-\frac{3}{2}\),所以在\([1, n]\)范围内的根只有一个。
所以直接暴力即可,因为\(i\)的枚举量大概在\(\mathcal{O}(\sqrt{n})\)

代码:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
ll n, k;
 
ll f(int x) {
    return 1ll * x * (x + 1) / 2;
}
 
int main() {
    while (scanf("%lld%lld", &n, &k) != EOF) {
        for (int i = 1; i <= n; ++i) {
            if (f(i) - (n - i) == k) {
                printf("%lld\n", n - i);
                break;
            }
        }
    }
    return 0;
}

C. Basketball Exercise

题意:
有两排人,每排\(n\)个人,现在要求在这两排人中选出一些人,使得他们身高和最高,并且满足以下限制:

  • 每一排中被选中的人数不能相邻
  • 选择的下标要是递增的

代码:
考虑\(f[i][0/1/2]\)表示到第\(i\)个列位置,选择的是第一排的人,还是第二排的人,还是这一列不选。
转移即可。

思路:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define N 100010
int n;
ll h[N][2], f[N][2];
 
int main() {
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &h[i][0]);
        }
        for (int i = 1; i <= n; ++i) {
            scanf("%lld", &h[i][1]);
        }
        memset(f, 0, sizeof f);
        f[1][0] = h[1][0];
        f[1][1] = h[1][1];
        ll res = 0;
        for (int i = 2; i <= n; ++i) {
            f[i][0] = h[i][0] + f[i - 1][1];
            f[i][1] = h[i][1] + f[i - 1][0];
            if (i > 2) {
                f[i][0] = max(f[i][0], h[i][0] + max(f[i - 2][0], f[i - 2][1]));
                f[i][1] = max(f[i][1], h[i][1] + max(f[i - 2][0], f[i - 2][1]));
            }
        }
        for (int i = 1; i <= n; ++i) {
            for (int j = 0; j < 2; ++j) {
                res = max(res, f[i][j]);
            }
        }
        printf("%lld\n", res);
    }
    return 0;
}

D1. Submarine in the Rybinsk Sea (easy edition)

题意:
定义拼接函数\(f(a_1a_2 \cdots a_p, b_1b_2 \cdots b_q)\)
\[ f(a_1 \cdots a_p, b_1 \cdots b_q) = \left\{ \begin{array}{cccc} a_1a_2 \cdots a_{p - q +1}b_1a_{p - q + 2}b_2 \cdots a_{p - 1}b_{q - 1}a_pb_p && p \leq q \\ b_1b_2 \cdots b_{q - p}a_1b_{q - p + 1}a_2 \cdots a_{p - 1}b_{q - 1}a_pb_q && p < q \end{array} \right. \]
再给出一个序列\(a_i\),询问:
\[ \begin{eqnarray*} \sum\limits_{i = 1}^n\sum\limits_{j = 1}^n f(a_i, a_j) \bmod 998244353 \end{eqnarray*} \]
在这里保证\(a_i\)的位数相同。

思路:
既然位数相同,那么我们就知道\(f(a_i, ?)\)\(a_i\)的贡献,以及\(f(?, a_i)\)\(a_i\)的贡献,分别计算即可。

代码:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define N 100010
const ll p = 998244353;
int n, a[N], len;
 
int getlen(int x) {
    int res = 0;
    while (x) {
        ++res;
        x /= 10;
    }
    return res;
}
 
ll f(ll x) {
    ll tot = 0;
    vector <int> vec;
    while (x) {
        vec.push_back(x % 10);
        x /= 10;
    }
    reverse(vec.begin(), vec.end());
    for (auto it : vec) {
        tot = tot * 10 + it;
        tot = tot * 10 + it;
        tot %= p;   
    }
    return tot * n % p; 
}
 
int main() {
    while (scanf("%d", &n) != EOF) {
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
        }
        len = getlen(a[1]);
        ll res = 0;
        for (int i = 1; i <= n; ++i) {
            res += f(a[i]);
            res %= p;
        }
        printf("%lld\n", res);
    }
    return 0;
}

D2. Submarine in the Rybinsk Sea (hard edition)

题意:
\(D1\),但是不保证\(a_i\)位数相同。

思路:
位数最多只有\(10\)位,直接暴枚\(a_i\)对应的\(a_j\)的不同位数的贡献即可。
\(10^9\)是一个十位的数字。

代码:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define N 100010
const ll p = 998244353;
int n, a[N], num[N];
vector <vector<int>> vec;
int sze[20];
 
int getlen(int x) {
    int res = 0;
    while (x) {
        ++res;
        x /= 10;
    }
    return res;
}  
 
ll f(ll x, int a, int b, int n) {
    vector <int> vec, A(22, 0);
    while (x) {
        vec.push_back(x % 10);
        x /= 10;
    }
    reverse(vec.begin(), vec.end());
    int len = a + b; 
    if (a >= b) {
        auto it = vec.begin();
        for (int i = 1; i <= a - b + 1; ++i) {
            A[i] = *it;
            ++it;
        }
        for (int i = a - b + 3; i <= len; i += 2) {
            A[i] = *it;
            ++it;
        }
    } else {
        auto it = vec.begin();
        for (int i = b - a + 1; i <= len; i += 2) {
            A[i] = *it;
            ++it;
        }
    }
//  for (int i = 1; i <= len; ++i) printf("%d%c", A[i], " \n"[i == len]);
    ll tot = 0;
    for (int i = 1; i <= len; ++i) {
        tot = tot * 10 + A[i];
        tot %= p;
    }
    return tot * n % p;
}
 
ll g(ll x, int b, int a, int n) {
    vector <int> vec, A(22, 0);
    while (x) {
        vec.push_back(x % 10);
        x /= 10;
    }
    reverse(vec.begin(), vec.end());
    int len = a + b;
    if (a >= b) {
        auto it = vec.begin();
        for (int i = a - b + 2; i <= len; i += 2) {
            A[i] = *it;
            ++it;
        }
    } else {
        auto it = vec.begin();
        for (int i = 1; i <= b - a; ++i) {
            A[i] = *it;
            ++it;
        }
        for (int i = b - a + 2; i <= len; i += 2) {
            A[i] = *it;
            ++it;
        }
    }
    ll tot = 0;
    for (int i = 1; i <= len; ++i) {
        tot = tot * 10 + A[i];
        tot %= p;
    }
    return tot * n % p;
}
 
int main() {
    while (scanf("%d", &n) != EOF) {
        vec.clear();
        vec.resize(20);
        for (int i = 1; i <= n; ++i) {
            scanf("%d", a + i);
            vec[getlen(a[i])].push_back(a[i]);  
        }
        for (int i = 1; i <= 10; ++i) sze[i] = (int)vec[i].size();
        ll res = 0;
        for (int i = 1; i <= 10; ++i) if (sze[i]) {
            for (auto it : vec[i]) {
                for (int j = 1; j <= 10; ++j) if (sze[j]) {
                    res += f(it, i, j, sze[j]);
                    res %= p;
                    res += g(it, i, j, sze[j]); 
                    res %= p;
                }
            }
        }
        printf("%lld\n", res);
    }
    return 0;
}

E. OpenStreetMap

题意:
\(n \cdot m\)的矩形中\(a \cdot b\)的所有小矩形的最小值之和。

思路:
二维\(RMQ\)是过不去的。。
考虑复杂度肯定为\(\mathcal{O}(nm)\)
我们可以竖着枚举矩形右下角,然后再横着枚举。
考虑用\(3000\)个单调队列维护每一行枚举到的最小值,再用一个单调队列维护\(a \cdot b\)矩形内的最小值。
注意加点的时间以及删点的判断。

代码:

#include <bits/stdc++.h>
using namespace std;
 
#define ll long long
#define N 3010
int n, m, a, b;
ll g[N * N], x, y, z;
int B[N][N], l[N], r[N], que[N], L, R;   
 
int get(int x, int y) {
    return (x - 1) * m + y - 1;
}
 
int main() {
    while (scanf("%d%d%d%d", &n, &m, &a, &b) != EOF) {
        L = 1, R = 0;
        for (int i = 1; i <= n; ++i) l[i] = 1, r[i] = 0;
        scanf("%lld%lld%lld%lld", g, &x, &y, &z);
        for (int i = 1; i <= n * m; ++i) g[i] = (g[i - 1] * x + y) % z;
        for (int i = 1; i <= n; ++i) {
            for (int j = 1; j < b; ++j) {
                while (l[i] <= r[i] && g[get(i, j)] < g[B[i][r[i]]]) {
                    --r[i];
                }
                B[i][++r[i]] = get(i, j); 
            }
        }   
        ll res = 0;
        for (int i = 1; i <= a; ++i) {
            while (L <= R && g[B[i][l[i]]] < g[que[R]]) --R; 
            que[++R] = B[i][l[i]];
        }
        for (int j = b; j <= m; ++j) {
            for (int i = 1; i <= n; ++i) {
                while (l[i] <= r[i] && abs(B[i][l[i]] - get(i, j)) >= b) ++l[i];
                while (l[i] <= r[i] && g[get(i, j)] < g[B[i][r[i]]]) --r[i];
                B[i][++r[i]] = get(i, j);
            }
            L = 1, R = 0;
            for (int i = 1; i < a; ++i) {
                while (L <= R && g[B[i][l[i]]] < g[que[R]]) --R;
                que[++R] = B[i][l[i]];
            }
            for (int i = a; i <= n; ++i) {
                while (L <= R && abs(que[L] - get(i, j)) >= (a - 1) * m + b) ++L;
                while (L <= R && g[B[i][l[i]]] < g[que[R]]) --R;
                que[++R] = B[i][l[i]];
                res += g[que[L]];
            }
        }
        printf("%lld\n", res);
    }
    return 0;
}

转载于:https://www.cnblogs.com/Dup4/p/11204775.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动控制节水灌溉技术的高低代表着农业现代化的发展状况,灌溉系统自动化水平较低是制约我国高效农业发展的主要原因。本文就此问题研究了单片机控制的滴灌节水灌溉系统,该系统可对不同土壤的湿度进行监控,并按照作物对土壤湿度的要求进行适时、适量灌水,其核心是单片机和PC机构成的控制部分,主要对土壤湿度与灌水量之间的关系、灌溉控制技术及设备系统的硬件、软件编程各个部分进行了深入的研究。 单片机控制部分采用上下位机的形式。下位机硬件部分选用AT89C51单片机为核心,主要由土壤湿度传感器,信号处理电路,显示电路,输出控制电路,故障报警电路等组成,软件选用汇编语言编程。上位机选用586型以上PC机,通过MAX232芯片实现同下位机的电平转换功能,上下位机之间通过串行通信方式进行数据的双向传输,软件选用VB高级编程语言以建立友好的人机界面。系统主要具有以下功能:可在PC机提供的人机对话界面上设置作物要求的土壤湿度相关参数;单片机可将土壤湿度传感器检测到的土壤湿度模拟量转换成数字量,显示于LED显示器上,同时单片机可采用串行通信方式将此湿度值传输到PC机上;PC机通过其内设程序计算出所需的灌水量和灌水时间,且显示于界面上,并将有关的灌水信息反馈给单片机,若需灌水,则单片机系统启动鸣音报警,发出灌水信号,并经放大驱动设备,开启电磁阀进行倒计时定时灌水,若不需灌水,即PC机上显示的灌水量和灌水时间均为0,系统不进行灌水。
智慧农业是一种结合了现代信息技术,包括物联网、大数据、云计算等,对农业生产过程进行智能化管理和监控的新模式。它通过各种传感器和设备采集农业生产中的关键数据,如大气、土壤和水质参数,以及生物生长状态等,实现远程诊断和精准调控。智慧农业的核心价值在于提高农业生产效率,保障食品安全,实现资源的可持续利用,并为农业产业的转型升级提供支持。 智慧农业的实现依赖于多个子系统,包括但不限于设施蔬菜精细化种植管理系统、农业技术资料库、数据采集系统、防伪防串货系统、食品安全与质量追溯系统、应急追溯系统、灾情疫情防控系统、农业工作管理系统、远程诊断系统、监控中心、环境监测系统、智能环境控制系统等。这些系统共同构成了一个综合的信息管理和服务平台,使得农业生产者能够基于数据做出更加科学的决策。 数据采集是智慧农业的基础。通过手工录入、传感器自动采集、移动端录入、条码/RFID扫描录入、拍照录入以及GPS和遥感技术等多种方式,智慧农业系统能够全面收集农业生产过程中的各种数据。这些数据不仅包括环境参数,还涵盖了生长状态、加工保存、检验检疫等环节,为农业生产提供了全面的数据支持。 智慧农业的应用前景广阔,它不仅能够提升农业生产的管理水平,还能够通过各种应用系统,如库房管理、无公害监控、物资管理、成本控制等,为农业生产者提供全面的服务。此外,智慧农业还能够支持政府监管,通过发病报告、投入品报告、死亡报告等,加强农业产品的安全管理和质量控制。 面对智慧农业的建设和发展,存在一些挑战,如投资成本高、生产过程标准化难度大、数据采集和监测的技术难题等。为了克服这些挑战,需要政府、企业和相关机构的共同努力,通过政策支持、技术创新和教育培训等手段,推动智慧农业的健康发展。智慧农业的建设需要明确建设目的,选择合适的系统模块,并制定合理的设备布署方案,以实现农业生产的智能化、精准化和高效化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值