比赛链接

传送门

A题

题意

\(n\)个人每个人都有自己喜欢喝的\(vechorka\)口味,现在给你\(\lceil n/2\rceil\)箱\(vechorka\),每箱有两瓶,问最多能有多少个人能拿到自己喜欢的口味。

思路

我们首先记录每个口味有多少个人喜欢,然后要想拿到自己喜欢的口味最大那么一定要优先考虑能凑偶数的,把偶数考虑完后剩余的口味一定都是\(1\),就不管怎么分都只能满足一半的人。

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://Code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, k;
int a[maxn], num[maxn]; int main() {
scanf("%d%d", &n, &k);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
num[a[i]]++;
}
int ans = 0;
int tot = (n + 1) / 2;
for(int i = 1; i <= k; ++i) {
ans += num[i] / 2 * 2;
tot -= num[i] / 2;
num[i] %= 2;
}
ans += tot;
printf("%d\n", ans);
return 0;
}

B题

题意

要你使用恰好\(n\)次操作使得总糖果数为\(k\),操作分为两种:

  • 增加上一次增加的数量\(+1\)个糖果;
  • 减少\(1\)个糖果。

思路

二分\(check\)。

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://Code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e6 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, k; bool check(int x) {
return (1LL * x * x + 3LL * x) / 2 - n >= k;
} int main() {
scanf("%d%d", &n, &k);
int ub = n, lb = 1, mid, ans = 0;
while(ub >= lb) {
mid = (ub + lb) >> 1;
if(check(mid)) {
ans = mid;
ub = mid - 1;
} else {
lb = mid + 1;
}
}
printf("%d\n", n - ans);
return 0;
}

C题

题意

总共有\(2n\)个人,第一排的编号从\(1\)到\(n\),第二排也是,现在要你选择任意多个人使得总身高最大,但是注意同一个编号只能有一个人,编号相邻的话不能是同一排的。

思路

\(dp[i][j]\)表示编号为\(i\)的人选择状态为\(j\)时的最大身高,\(j=0\)表示从第一排选,\(j=1\)从第二排,\(j=2\)为不选,则\(dp[i][0]=max(dp[i-1][1],dp[i-1][2])+a[i],dp[i][1]=max(dp[i-1][0],dp[i-1][2])+b[i],dp[i][2]=max(dp[i-1][0],dp[i-1][1],dp[i-1][2])\)。

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://Code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 1e9 + 7;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n;
int a[maxn], b[maxn];
LL dp[maxn][3]; int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) {
scanf("%d", &a[i]);
}
for(int i = 1; i <= n; ++i) {
scanf("%d", &b[i]);
}
for(int i = 1; i <= n; ++i) {
dp[i][0] = max(dp[i-1][1], dp[i-1][2]) + a[i];
dp[i][1] = max(dp[i-1][0], dp[i-1][2]) + b[i];
dp[i][2] = max(dp[i-1][0], max(dp[i-1][1], dp[i-1][2]));
}
printf("%lld\n", max(dp[n][0], max(dp[n][1], dp[n][2])));
return 0;
}

D题

题意

定义\(f\)函数为

如果\(p\geq q\):\(f(a1…ap,b1…bq)=a_1a_2\dots a_{p−q+1}b_1a{p−q+2}b_2\dots a_{p−1}b_{q−1}a_pb_q\);

如果\(p<q\):\(f(a_1\dots a_p,b_1\dots b_q)=b_1b_2…b_{q−p}a_1b_{q−p+1}a_2\dots a_{p−1}b{q−1}a_pb_q\).

思路

按位算贡献,先预处理出\(a_i\)与长度\(len\)的数进行\(f\)函数的贡献然后乘以长度为\(len\)的数的个数。

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://Code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 998244353;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n;
int a[maxn], pw[105], cnt[30];
LL dp[maxn][30]; int main() {
scanf("%d", &n);
pw[0] = 1;
for(int i = 1; i < 30; ++i) {
pw[i] = 1LL * pw[i-1] * 10 % mod;
}
for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
for(int i = 1; i <= n; ++i) {
int x = a[i], len = 0;
while(x) {
++len;
x /= 10;
}
cnt[len]++;
for(int j = 1; j <= 10; ++j) {
if(len >= j) {
int num = a[i];
for(int k = 0; k < j; ++k) {
int x = num % 10;
num /= 10;
dp[i][j] = (((dp[i][j] + 1LL * x * pw[k*2] % mod) % mod) + 1LL * x * pw[k*2+1] % mod) % mod;
}
int pp = 2 * j;;
for(int k = j; k < len; ++k) {
int x = num % 10;
num /= 10;
dp[i][j] = (dp[i][j] + 2LL * x * pw[pp] % mod) % mod;
++pp;
}
} else {
int num = a[i];
for(int k = 0; k < len; ++k) {
int x = num % 10;
num /= 10;
dp[i][j] = (((dp[i][j] + 1LL * x * pw[k*2] % mod) % mod) + 1LL * x * pw[k*2+1] % mod) % mod;
}
}
}
}
LL ans = 0;
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= 10; ++j) {
ans = (ans + 1LL * dp[i][j] * cnt[j] % mod) % mod;
}
}
printf("%lld\n", ans);
return 0;
}

E题

题意

给你构造\(n\times m\)的矩阵的公式然后要你求所有大小为\(a\times b\)的子矩阵内最小值的和。

思路

首先我们先通过暴力将矩阵构造出来,然后对每一行用单调队列求出最小值,然后再把这个值当成\(mp[i][j]\)再对每一列求一次然后累加即可。

代码实现如下

#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cstdlib>
#include <cstring>
#include <cassert>
#include <iostream>
#include <algorithm>
#include <unordered_map>
using namespace std; typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL; #define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("D://Code//in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0) const double eps = 1e-8;
const int mod = 998244353;
const int maxn = 1e5 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL; int n, m, a, b;
LL g, x, y, z;
int mp[3002][3002], dp[3002][3002];
deque<pii> q; int main() {
scanf("%d%d%d%d", &n, &m, &a, &b);;
scanf("%lld%lld%lld%lld", &g, &x, &y, &z);
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
mp[i][j] = g;
g = (1LL * g * x % z + y) % z;
}
}
for(int i = 1; i <= n; ++i) {
while(!q.empty()) q.pop_back();
for(int j = m; j >= 1; --j) {
while(!q.empty() && mp[i][j] < q.front().first) q.pop_front();
q.push_front({mp[i][j], j});
dp[i][j] = q.back().first;
while(!q.empty() && q.back().second >= j + b - 1) q.pop_back();
}
}
for(int i = 1; i <= n; ++i) {
for(int j = 1; j <= m; ++j) {
mp[i][j] = dp[i][j];
}
}
for(int j = 1; j <= m; ++j) {
while(!q.empty()) q.pop_back();
for(int i = n; i >= 1; --i) {
while(!q.empty() && mp[i][j] < q.front().first) q.pop_front();
q.push_front({mp[i][j], i});
dp[i][j] = q.back().first;
while(!q.empty() && q.back().second >= i + a - 1) q.pop_back();
}
}
LL ans = 0;
for(int i = 1; i <= n - a + 1; ++i) {
for(int j = 1; j <= m - b + 1; ++j) {
ans += dp[i][j];
}
}
printf("%lld\n", ans);
return 0;
}

Codeforces Round #574 (Div. 2)题解的更多相关文章

  1. Codeforces Round #182 (Div. 1)题解【ABCD】

    Codeforces Round #182 (Div. 1)题解 A题:Yaroslav and Sequence1 题意: 给你\(2*n+1\)个元素,你每次可以进行无数种操作,每次操作必须选择其 ...

  2. Codeforces Round #608 (Div. 2) 题解

    目录 Codeforces Round #608 (Div. 2) 题解 前言 A. Suits 题意 做法 程序 B. Blocks 题意 做法 程序 C. Shawarma Tent 题意 做法 ...

  3. Codeforces Round #525 (Div. 2)题解

    Codeforces Round #525 (Div. 2)题解 题解 CF1088A [Ehab and another construction problem] 依据题意枚举即可 # inclu ...

  4. Codeforces Round #528 (Div. 2)题解

    Codeforces Round #528 (Div. 2)题解 A. Right-Left Cipher 很明显这道题按题意逆序解码即可 Code: # include <bits/stdc+ ...

  5. Codeforces Round #466 (Div. 2) 题解940A 940B 940C 940D 940E 940F

    Codeforces Round #466 (Div. 2) 题解 A.Points on the line 题目大意: 给你一个数列,定义数列的权值为最大值减去最小值,问最少删除几个数,使得数列的权 ...

  6. Codeforces Round #677 (Div. 3) 题解

    Codeforces Round #677 (Div. 3) 题解 A. Boring Apartments 题目 题解 简单签到题,直接数,小于这个数的\(+10\). 代码 #include &l ...

  7. Codeforces Round #665 (Div. 2) 题解

    Codeforces Round #665 (Div. 2) 题解 写得有点晚了,估计都官方题解看完切掉了,没人看我的了qaq. 目录 Codeforces Round #665 (Div. 2) 题 ...

  8. Codeforces Round #160 (Div. 1) 题解【ABCD】

    Codeforces Round #160 (Div. 1) A - Maxim and Discounts 题意 给你n个折扣,m个物品,每个折扣都可以使用无限次,每次你使用第i个折扣的时候,你必须 ...

  9. Codeforces Round #383 (Div. 2) 题解【ABCDE】

    Codeforces Round #383 (Div. 2) A. Arpa's hard exam and Mehrdad's naive cheat 题意 求1378^n mod 10 题解 直接 ...

随机推荐

  1. Appium脚本(4) 使用uiautomator方法定位元素

    from app.find_element.capability import driver from time import sleep # 使用uiautomator方法定位元素 accunt_i ...

  2. C# COM组的开发以及调用

    一.用C#编写一个COM组件 1.       打开Visual Studio2008,[文件]->[新建]->[项目] 2.       项目类型=Visual C#,模版=类库,名称= ...

  3. c++动态链接问题

    https://blog.csdn.net/liu0808/article/details/81169173 https://blog.csdn.net/f110300641/article/deta ...

  4. java 堆调优

    一.查看kafka集群的broker的堆内存使用情况 1>.使用jstat查看gc的信息([root@kafka116 ~]# jstat -gc 12698 1s 30) 参数说明:S0C:第 ...

  5. Kubernetes 使用 Weave Scope 监控集群(十七)

    目录 一.安装 二.使用 Scope 2.1.拓扑结构 2.2.在线操作 2.3.强大的搜索功能 创建 Kubernetes 集群并部署容器化应用只是第一步.一旦集群运行起来,我们需要确保一起正常,所 ...

  6. 瀚云平台kafka简单原理

    客户端利用kafka 硬件 创建 productkey,cmd-productkey,conn-productkey为主题,代表设备数据,设备命令,设备事件. 客户端去订阅这三个主题 数据推送模拟器, ...

  7. 【LeetCode】 #7:反转整数 C语言

    目录 题目 思路 初步想法 进一步想法 总结 最近打算练习写代码的能力,所以从简单题开始做. 大部分还是用C语言来解决. @(解法) 题目 给出一个 32 位的有符号整数,你需要将这个整数中每位上的数 ...

  8. mysql连接不释放

    环境: 持久层:JPA 数据库连接池:druid 数据库中间件:Mycat 数据库:Mysql 报错: Unable to acquire JDBC Connection 排查步骤: 方法一: 1.d ...

  9. -Gradle 翻译 Merge AndroidManifest 合并清单文件 MD

    目录 目录 Merge AndroidManifest 合并清单文件 合并多个清单文件 合并优先级 合并冲突启发式算法 合并规则的标记 节点标记 属性标记 Attribute markers 标记选择 ...

  10. 【leetcode-91 动态规划】 解码方法

    一条包含字母 A-Z 的消息通过以下方式进行了编码: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 给定一个只包含数字的非空字符串,请计算解码方法的总数. 示例 1 ...