Educational Codeforces Round 21 

A. Lucky Year

个位数直接输出\(1\)

否则,假设\(n\)十进制最高位的值为\(s\),答案就是\(s-(n\mod s)\)

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define pb push_back
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);}; void solve(){
int a, b; sci(a); b = a;
int t = 0;
LL s = 1;
while(a) t++, a/=10, s *= 10;
s /= 10;
if(t==1) cout << 1 << endl;
else cout << s - (b % s) << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

B. Average Sleep Time

滑窗算一下就好了

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define pb push_back
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);}; void solve(){
int n, k; sci(n); sci(k);
LL s = 0;
vl A(n);
for(auto &x : A) scl(x);
for(int i = 0; i < k; i++) s += A[i];
LL tt = s;
for(int i = k; i < n; i++){
s += A[i]; s -= A[i-k];
tt += s;
}
cout << fixed << setprecision(10) << 1. * tt / (n - k + 1) << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

C. Tea Party

为了容易处理,先把所有\(a\)从小到大排序

先让所有值都等于\(\lceil a_i\rceil\),不够用输出\(NO\)

如果有剩下的,从最大的开始把剩下的补进去即可

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define pb push_back
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);}; void solve(){
int n, m;
sci(n); sci(m);
vector<pii> A(n);
vi B(n);
for(auto &x : A) sci(x.first);
for(int i = 0; i < n; i++) A[i].second = i;
sort(all(A));
for(int i = 0; i < n; i++){
B[i] = (A[i].first + 1) / 2;
m -= B[i];
}
if(m<0){
cout << -1 << endl;
return;
}
int x = min(m,A.back().first - B.back());
B.back() += x; m -= x;
for(int i = n - 2; i >= 0; i--){
x = min(m, min(B[i+1],A[i].first) - B[i]);
m -= x; B[i] += x;
}
vi ret(n);
for(int i = 0; i < n; i++) ret[A[i].second] = B[i];
for(int i = 0; i < n; i++) cout << ret[i] << ' ';
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

D. Array Division

维护一个前缀和和后缀和,然后判断是否存在一个数从前缀中放到后缀或者从后缀中放到前缀使得前后缀和相等,用个\(map\)计一下就好了

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define pb push_back
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);}; void solve(){
int n; sci(n);
vi A(n);
for(int &x : A) sci(x);
LL s = accumulate(all(A),0ll);
if(s&1){
cout << "NO" << endl;
return;
}
LL pre = 0;
map<LL,int> s1,s2;
for(int x : A) s2[x]++;
for(int i = 0; i < n; i++){
pre += A[i];
s1[A[i]]++; s2[A[i]]--;
if(s2[A[i]]==0) s2.erase(A[i]);
LL delta = 2 * pre - s;
if(delta==0 or (delta<0 and s2.count(-delta/2)) or (delta>0 and s1.count(delta/2))){
cout << "YES" << endl;
return;
}
}
cout << "NO" << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

E. Selling Souvenirs

\(w\)比较小,考虑从这里找到解决方法

如果\(w\)只有两种的话直接从大到小排序后枚举一种的数量,然后另一种直接计算就好了

现在\(w\)有三种,那么我们枚举\(w=3\)的,如果暴力枚举\(w=2\)的复杂度会有\(O(n^2)\)

假设我们选完\(w=3\)的之后全选了\(w=1\)的,可以发现我们每次相当于拿一个\(w=2\)的去替换两个\(w=1\)的

考虑最贪心的情况下,肯定是拿值最大的\(w=2\)去替换两个值最小的\(w=1\)的物品

那么我们可以二分这个替换的数量

复杂度\(O(n\log n)\)

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define pb push_back
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);}; void solve(){
int n, m;
sci(n); sci(m);
vl A[3],pre[3];
for(int i = 0; i < n; i++){
int x, y; sci(x); sci(y);
A[x-1].push_back(y);
}
for(int i = 0; i < 3; i++){
sort(all(A[i]),greater<LL>());
A[i].insert(A[i].begin(),0);
partial_sum(all(A[i]),back_inserter(pre[i]));
}
while(A[0].size()<=m){
A[0].push_back(0);
pre[0].push_back(pre[0].back());
}
LL ret = 0;
for(int i = 0; i < A[2].size() and i <= m / 3; i++){
LL sum = pre[2][i];
int lft = m - 3 * i;
if(A[1].size()==1){
ret = max(ret,sum+pre[0][lft]);
continue;
}
int l = 1, r = min((int)A[1].size()-1,lft/2);
while(l<=r){
int mid = (l + r) >> 1;
if(A[1][mid]>A[0][lft-(mid-1)*2]+A[0][lft-(mid-1)*2-1]) l = mid + 1;
else r = mid - 1;
}
ret = max(ret,sum + pre[1][r] + pre[0][lft-2*r]);
}
cout << ret << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

F. Card Game

除了\(2\)以外的所有偶数都不是素数

并且显然我们不会取两张编号为\(1\)的卡

所以我们把所有可以用的卡片按编号的奇偶分成两部分,如果和为素数就连边,可以发现这是一张二分图

源点向所有偶数点连边,容量为价值,所有奇数点向汇点连边,容量为价值,不能同时存在的两个点连容量为\(INF\)的边

那么可以得到的最大价值和就是价值和减去最小割

那么我们二分\(level\)然后网络流判断就好了

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define pb push_back
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 222;
#define S 0
#define T MAXN - 1
struct EDGE{
int to,cap,rev;
EDGE(){};
EDGE(int to, int cap, int rev):to(to),cap(cap),rev(rev){};
};
vector<EDGE> G[MAXN];
int iter[MAXN],rk[MAXN];
void ADDEDGE(int u, int v, int cap){
G[u].push_back(EDGE(v,cap,(int)G[v].size()));
G[v].push_back(EDGE(u,0,(int)G[u].size()-1));
}
bool bfs(){
memset(rk,0,sizeof(rk));
memset(iter,0,sizeof(iter));
rk[S] = 1;
queue<int> que;
que.push(S);
while(!que.empty()){
int u = que.front();
que.pop();
for(auto e : G[u]){
if(!e.cap or rk[e.to]) continue;
rk[e.to] = rk[u] + 1;
que.push(e.to);
}
}
return rk[T]!=0;
}
int dfs(int u, int flow){
if(u==T) return flow;
for(int &i = iter[u]; i < (int)G[u].size(); i++){
auto &e = G[u][i];
if(!e.cap or rk[e.to]!=rk[u]+1) continue;
int d = dfs(e.to,min(e.cap,flow));
if(d){
e.cap -= d;
G[e.to][e.rev].cap += d;
return d;
}
}
return 0;
}
int Dinic(){
int flow = 0;
while(bfs()){
int d = dfs(S,INF);
while(d){
flow += d;
d = dfs(S,INF);
}
}
return flow;
}
const int MAXM = 2e5+7;
int n, k, prime[MAXM], pri_cnt;
bool npm[MAXM];
vector<pii> card[MAXN]; void sieve(){
for(int i = 2; i < MAXM; i++){
if(!npm[i]) prime[++pri_cnt] = i;
for(int j = 1; i * prime[j] < MAXM; j++){
npm[i*prime[j]] = true;
if(i%prime[j]==0) break;
}
}
}
void solve(){
sieve();
sci(n), sci(k);
for(int i = 1; i <= n; i++){
int x, y, z;
sci(x), sci(y), sci(z);
card[z].pb({x,y});
}
int l = 1, r = n;
while(l<=r){
int mid = (l + r) >> 1;
vector<pii> odd, even;
int val1 = 0;
for(int i = 0; i < MAXN; i++) G[i].clear();
for(int i = 1; i <= mid; i++) for(auto p : card[i]){
if(p.second==1) cmax(val1,p.first);
else if(p.second&1) odd.pb(p);
else even.pb(p);
}
if(val1) odd.pb({val1,1});
int sum = 0;
for(auto p : odd) sum += p.first;
for(auto p : even) sum += p.first;
for(int i = 0; i < (int)even.size(); i++) ADDEDGE(i+1+odd.size(),T,even[i].first);
for(int i = 0; i < (int)odd.size(); i++){
ADDEDGE(S,i+1,odd[i].first);
for(int j = 0; j < (int) even.size(); j++) if(!npm[odd[i].second+even[j].second]) ADDEDGE(i+1,j+1+odd.size(),INF);
}
if(sum - Dinic()>=k) r = mid - 1;
else l = mid + 1;
}
cout << (l==n+1?-1:l) << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

G. Anthem of Berland

匹配问题,考虑类似\(KMP\)的做法,先根据\(t\)串得到\(fail\)数组,然后类似\(AC\)自动机,得到每个位置匹配下一个字符到的位置

然后考虑\(dp\),\(dp[i][j]\)表示现在\(s\)串的\(i\)位置匹配到了\(t\)串的\(j\)位置完美匹配的最多次数,遇到字母直接转移,否则枚举\(26\)个字母转移即可

view code
#pragma GCC optimize("O3")
#pragma GCC optimize("Ofast,no-stack-protector")
#include<bits/stdc++.h>
using namespace std;
#define INF 0x3f3f3f3f
#define LL long long int
#define vi vector<int>
#define vl vector<LL>
#define pb push_back
#define all(V) V.begin(),V.end()
#define sci(x) scanf("%d",&x)
#define scl(x) scanf("%I64d",&x)
#define pii pair<int,int>
#define cmax(a,b) ((a) = (a) > (b) ? (a) : (b))
#define cmin(a,b) ((a) = (a) < (b) ? (a) : (b))
#define debug(x) cerr << #x << " = " << x << endl
function<void(void)> ____ = [](){ios_base::sync_with_stdio(false); cin.tie(0); cout.tie(0);};
const int MAXN = 1e5+7;
char s[MAXN], t[MAXN];
int fail[MAXN], ch[MAXN][26], n, m; void solve(){
scanf("%s %s",s+1,t+1);
n = strlen(s+1), m = strlen(t+1);
for(int i = 2, len = 0; i <= m;){
if(t[i]==t[len+1]) fail[i++] = ++len;
else{
if(len) len = fail[len];
else fail[i++] = len;
}
}
for(int i = 0; i < m; i++){
for(int j = 0; j < 26; j++) ch[i][j] = ch[fail[i]][j];
ch[i][t[i+1]-'a'] = i + 1;
}
vector<vi> f(n+1,vi(m+1,-1));
f[0][0] = 0;
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
if(f[i][j]==-1) continue;
for(int k = (s[i+1]=='?'?0:s[i+1]-'a'); k < (s[i+1]=='?'?26:s[i+1]-'a'+1); k++){
if(ch[j][k]==m) cmax(f[i+1][fail[m]],f[i][j] + 1);
else cmax(f[i+1][ch[j][k]],f[i][j]);
}
}
}
cout << *max_element(all(f[n])) << endl;
}
int main(){
#ifndef ONLINE_JUDGE
freopen("Local.in","r",stdin);
freopen("ans.out","w",stdout);
#endif
solve();
return 0;
}

Educational Codeforces Round 21的更多相关文章

  1. Educational Codeforces Round 21 D.Array Division(二分)

    D. Array Division time limit per test:2 seconds memory limit per test:256 megabytes input:standard i ...

  2. Educational Codeforces Round 21(A.暴力,B.前缀和,C.贪心)

    A. Lucky Year time limit per test:1 second memory limit per test:256 megabytes input:standard input ...

  3. Educational Codeforces Round 21 Problem E(Codeforces 808E) - 动态规划 - 贪心

    After several latest reforms many tourists are planning to visit Berland, and Berland people underst ...

  4. Educational Codeforces Round 21 Problem D(Codeforces 808D)

    Vasya has an array a consisting of positive integer numbers. Vasya wants to divide this array into t ...

  5. Educational Codeforces Round 21 Problem A - C

    Problem A Lucky Year 题目传送门[here] 题目大意是说,只有一个数字非零的数是幸运的,给出一个数,求下一个幸运的数是多少. 这个幸运的数不是最高位的数字都是零,于是只跟最高位有 ...

  6. Educational Codeforces Round 21 A-E题题解

    A题      ............太水就不说了,贴下代码 #include<string> #include<iostream> #include<cstring& ...

  7. Educational Codeforces Round 21 Problem F (Codeforces 808F) - 最小割 - 二分答案

    Digital collectible card games have become very popular recently. So Vova decided to try one of thes ...

  8. CF Educational Codeforces Round 21

    A. Lucky Year time limit per test 1 second memory limit per test 256 megabytes input standard input ...

  9. Educational Codeforces Round 21 D - Array Division (前缀和+二分)

    传送门 题意 将n个数划分为两块,最多改变一个数的位置, 问能否使两块和相等 分析 因为我们最多只能移动一个数x,那么要么将该数往前移动,要么往后移动,一开始处理不需要移动的情况 那么遍历sum[i] ...

随机推荐

  1. Mac上“您没有权限来打开应用程序”(Big Sur)

    最近电脑更新了Macos的最新11版大苏尔 Big Sur.很快问题就出现了:安装某个软件的时候Key Gen打不开,提示您没有权限来打开应用程序,类似这样:https://zhuanlan.zhih ...

  2. Oracle误删数据的恢复

    Oracle误删数据的恢复,分为两种方法:SCN和时间戳两种方法恢复. 一.通过SCN恢复删除且已提交的数据 1.获得当前数据库的SCN号 select current_scn from v$data ...

  3. 计算机考研复试真题 N阶楼梯上楼问题

    题目描述 N阶楼梯上楼问题:一次可以走两阶或一阶,问有多少种上楼方式.(要求采用非递归) 输入描述: 输入包括一个整数N,(1<=N<90). 输出描述: 可能有多组测试数据,对于每组数据 ...

  4. #2020征文-开发板# 用鸿蒙开发AI应用(五)HDF 驱动补光灯

    目录: 前言 硬件准备 HDF 驱动开发 总结 前言上一篇,我们在鸿蒙上运行了第一个程序,这一篇我们来编写一个驱动开启摄像头的红外补光灯,顺便熟悉一下鸿蒙上的 HDF 驱动开发. 硬件准备先查一下原理 ...

  5. linux最大打开文件句柄数

    linux最大打开文件句柄数,即打开文件数最大限制,就是规定的单个进程能够打开的最大文件句柄数量(Socket连接也算在里面,默认大小1024) liunx中文件句柄有两个限制,一种是用户级的,一种是 ...

  6. java锁的对象引用

    当访问共享的可变数据时,通常需要同步.一种避免使用同步的方式就是不共享数据. 如果数据仅在单线程内访问,就不需要同步,这种技术称为"线程封闭",它是实现线程安全性最简单方式之一. ...

  7. SAP系统跨平台字符编码转换

    SAP系统在进行了夸平台的迁移,可能会遇到操作系统层文件编码不同,导致SAP系统无法识别或者乱码的问题.例如SAP系统从AIX平台迁移到linux平台,SAP应用服务器的编码会发生变化,从4102变化 ...

  8. 如何用Python中自带的Pandas和NumPy库进行数据清洗

    一.概况 1.数据清洗到底是在清洗些什么? 通常来说,你所获取到的原始数据不能直接用来分析,因为它们会有各种各样的问题,如包含无效信息,列名不规范.格式不一致,存在重复值,缺失值,异常值等..... ...

  9. linux自定义安装位置安装jdk

    注:本文系参考网络内容及本人实践得出 1 下载jdk安装包 下载地址:https://www.oracle.com/java/technologies/javase/javase-jdk8-downl ...

  10. Windows Server 2008 R2系统安装

    把系统U盘插到服务器上,然后启动服务器进入BIOS界面选择U盘启动. 根据服务器的不同,进入BIOS界面的按钮也不一样,主流的有F10.F11.F12.F2.ESC.delete等. 在从BIOS启动 ...