比赛链接

传送门

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. 【ARM-Linux开发】OpenACC并行编程实战笔记

    今年运气比较好,学了cuda之后,了解到了gpu的另两种使用语言opencl和openacc,  opencl(Open Computing Language ,开放计算语言)是面向异构系统的并行编程 ...

  2. 进程退出:SIGINT、SIGTERM和SIGKILL区别

    一.SIGINT.SIGTERM和SIGKILL区别 SIGINT与SIGTERM区别1)SIGINT关联ctrl+c2)SIGINT只能结束前台进程3)通过ctrl+c对当前进程发送结束信号,信号被 ...

  3. myeclipse的ctrl+f搜索面板功能详解

    1.查找/替换方向:Direction Forward:向前 Backward:向后 2.范围:Scope All:全部(当前文件) Selected lines:选中的几行 3.选项:Options ...

  4. Slenium入门

    selenium 为浏览器测试框架,可以调用浏览器webdriver模拟浏览器操作360打开Chrome: from selenium import webdriver from selenium.w ...

  5. 前端与算法 leetcode 28.实现 strStr()

    # 前端与算法 leetcode 28.实现 strStr() 题目描述 28.移除元素 概要 这道题的意义是实现一个api,不是调api,尽管很多时候api的速度比我们写的快(今天这个我们可以做到和 ...

  6. centos个性化命令行提示符

    为了在满屏的命令中找到用户的命令行,所以很有必要设置一种字体颜色.我就设置最实用的一种,可以用蓝色字体显示当前所在路径 命令行输入: echo "PS1='[\${debian_chroot ...

  7. MQTT的Res接口发布消息

    MQTT(这里采用的V2版本)发布消息的常见方法: 1.通过MQTT客户端连接MQTT服务器,建立长连接,通过接口发布消息 最常见的客户端: <dependency> <groupI ...

  8. [Docker] - 不同容器之间相互访问的实现方式(例如:Client 访问 DB)

    部署了两个独立的容器: Container #1 - Web ClientContainer #2 - SQL Server 不同容器间如何互访? 无法从 Container #1 访问到 Conta ...

  9. C_局部变量&全局变量

    2018-5-9   Writen By Stephen.Yu  一.定义 1. 局部变量:在函数中定义的变量 2. 全局变量:在所有函数体之外定义 定义(Definition):声明并分配内存;未分 ...

  10. java知识精要(二)

    java知识精要(一) 集合 Iterable v.s. Iterator 两者都是接口,在Collection继承的是Iterable. Iterable表达了集合具备迭代访问的能力,而Iterat ...