Codeforces Global Round 7
A. Bad Ugly Numbers
思路
- 题意: 给我们一个k,让我们用 0~9 之间的数字构成一个 k位数a,a不能被组成a的每一位数字整除。
- 分析:首先 k等于1,无论我们怎么配都会被整除;当k > 1 的时候,a的组成位数中肯定不能有1,那么只能在 2~9,之间选择,剩下我们可以选择两个不能互相整除的数如 2、7,,我们可以让2作为第一位,剩下的位数全是7,,,,例如我们求一个k = 3 时我们构成的数a,a = 277
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<string>
using namespace std;
int main()
{
/* freopen("A.txt","r",stdin); */
/* freopen("Res.txt","w",stdout); */
int t;
scanf("%d", &t);
while(t --)
{
int n;
scanf("%d", &n);
if(n == 1)
{
printf("-1\n");
continue;
}
printf("2");
for(int i = 2; i <= n; i ++)
printf("%d", 9);
printf("\n");
}
return 0;
}
- 注意:做题认真
B. Maximums(多观察)
思路
- 题意
有一个序列长度为n的序列a1,a2,,,an a_1,a_2,,,a_n~a1,a2,,,an ,有给了我们另一个序列x1,x2,x3...xn x_1,x_2,x_3...x_n~x1,x2,x3...xn ,在这个序列中xix_ixi为序列a从1~i-1 的前缀最大值,注意:x1=0x_1 = 0x1=0,又给了我们一个 b1,b2...bnb_1,b_2...b_nb1,b2...bn,其中bi=ai−xib_i = a_i - x_ibi=ai−xi, 题上给我们了 序列b的值,让我们逆向求序列a的值 - 分析:由于 xix_ixi是前缀1~(i - 1)位置序列a最大值,而且x1=0x_1 = 0x1=0, 我们要求的ai=bi+xia_i = b_i + x_iai=bi+xi, 当i = 1,x1,b1x_1, b_1x1,b1均为已知值,这样我们可以求出 a1a_1a1, 这样我们在维护 x1x_1x1的最大值,那么相当于x1x_1x1也是已知值,这样在不断求解每一位的时候,维护前缀最大值xix_ixi就行了
代码
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>
#include<map>
#include<queue>
#include<vector>
#include<string>
using namespace std;
const int Len = 2e5 + 10;
int ar[Len], br[Len];
int main()
{
/* freopen("A.txt","r",stdin); */
/* freopen("Res.txt","w",stdout); */
int n;
scanf("%d", &n);
for(int i = 1; i <= n; i ++)
scanf("%d", &br[i]);
int pri_mx = 0;
for(int i = 1; i <= n; i ++)
{
ar[i] = br[i] + pri_mx;
pri_mx = max(pri_mx, ar[i]);
}
for(int i = 1; i <= n; i ++)
printf("%d ", ar[i]);
return 0;
}
C. Permutation Partitions(思维)
思路
题意:给我们一个有1~n之间的数字组成的序列,让我们把这个序列分割成 k 段,是这k段中的最大值相加和最大,问我和的最大值是多少,并且得到这个最大值的分割方法有多少种。
分析:由于组成序列p是 1~n之间的数字,有很明显 和的最大值就是 n-k+1 ~ n 之间的所有数字和,这题就是难在这个分割方法,我们可以用
插板法去解决这个分割方法,我们加上 前k大数字在原序列p中的位置为x1,x2...xkx_1,x_2...x_kx1,x2...xk, 那么我们可以在 相邻的 两个属于前k大的数字之间进行插板,那么只需要查 k-1个板子就可解决问题了,对其中一个板子,插大位置的方案数是 x_i - x_i-1 ,那么我们把所有板子插入的位置方案数相乘就能得到ans了, ⚠️用 long long,防止相乘的时候溢出
代码
#include<iostream>
using namespace std;
typedef long long ll;
const int mod=998244353;
int n, k;
ll ans = 1, sum = 0, p = -1; //p存储的是上一个前k大的数的位置
int main()
{
/* freopen("A.txt","r",stdin); */
scanf("%d %d", &n, &k);
int x;
for(int i = 1; i <= n; i ++)
{
scanf("%d", &x);
if(x >= n - k + 1)
{
sum += x;
if(p != -1)
ans = ans * (i - p) % mod;
p = i;
}
}
printf("%lld %lld\n", sum, ans);
return 0;
}
- 收获:收获的肯定是,这个“插板法”来求解分割成连续k段的思路,真实考思维啊。。。。。
D2. Prefix-Suffix Palindrome (Hard version)(马拉车)
思路
题意:给我们一个字符串s,让我们从这个字符串中找到一个“前缀字符a串”(从s字符串开始的第一个字符为开头的子串) 和一个“后缀字符串b”(以s最后一个字符结尾的子串),把a 、b子串拼接起来,问能组成的最大回文字符串是多长。
分析:首先我们从s串中前后两端进行匹配,如果前后字符相同就继续向中间匹配,这样我们的到两端已经匹配好的子串设为x,y,把匹配剩下的一个连续的子串str,我们 “马拉车”算法跑一边,去求
以str中第一个字符开头的回文子串的的最大长度或者以str最后一个字符为结尾的回文子串的最大长度,得到的这个最大长度的回文子串的设为mid,那么最终答案就是 x + mid + z (把这三段拼接起来)⚠️:在用马拉车求解 mid最大回文子串 的时候,有以下代码片段需要注意:
//如果回文串从开头或者结尾出发 && 当前找到的这个回文串的长度大于 以前符合题意的回文串的长度
if(Len[i] - 1 > mx_ans && (i - Len[i] == 0 || i + Len[i] == tot))
{
if(i - Len[i] == 0)
is_front = 1;
else
is_front = 0;
mx_ans = Len[i] - 1;
}
代码
#include<iostream>
#include<cstring>
#include<string>
#include<algorithm>
using namespace std;
const int maxn = 5e6 + 5;
char ar[maxn], br[maxn], cr[maxn];
int Len[maxn];
bool is_front = 1;
int trans(int cnt)
{
int tot = 0;
cr[tot ++] = '@';
for(int i = 0; i < cnt; i ++)
cr[tot ++] = '#', cr[tot ++] = br[i];
cr[tot ++] = '#';
cr[tot] = '$';
return tot;
}
int Manacher(int tot)
{
int mid = 0, mxR = 0;
int mx_ans = 0;
for(int i = 1; i < tot; i ++)
{
if(i < mxR) Len[i] = min(mxR - i, Len[2*mid - i]);
else Len[i] = 1;
while(cr[i + Len[i]] == cr[i - Len[i]]) Len[i] ++;
if(mxR < i + Len[i])
{
mid = i;
mxR = i + Len[i];
}
//如果回文串从开头或者结尾出发 && 当前找到的这个回文串的长度大于 以前符合题意的回文串的长度
if(Len[i] - 1 > mx_ans && (i - Len[i] == 0 || i + Len[i] == tot))
{
if(i - Len[i] == 0)
is_front = 1;
else
is_front = 0;
mx_ans = Len[i] - 1;
}
}
return mx_ans;
}
int main()
{
/* freopen("A.txt","r",stdin); */
/* freopen("Res.txt","w",stdout); */
int t;
scanf("%d", &t);
while(t --)
{
is_front = 1;
scanf("%s", ar + 1);
int n = strlen(ar + 1);
int len1 = 0;
int cnt = 0;
for(int i = 1, j = n; i <= j; i ++, j --)
{
if(ar[i] == ar[j] && i != j)
len1 ++;
else
{
while(i <= j)
{
br[cnt ++] = ar[i];
i ++;
}
break;
}
}
int len2 = Manacher(trans(cnt));
for(int i = 1; i <= len1; i ++)
printf("%c", ar[i]);
if(is_front)
{
for(int i = 0; i < len2; i ++)
printf("%c", br[i]);
}
else
{
for(int i = cnt - len2; i < cnt; i ++)
printf("%c", br[i]);
}
for(int i = n - len1 + 1; i <= n; i ++)
printf("%c", ar[i]);
printf("\n");
}
return 0;
}
*收获:“马拉车”,这个神奇的以O(n)求回文的子串的算法。其次还是要好好读好题,把题意理解正确
E. Bombs(真思维 + 线段树)
思路
- 题意及分析:请看这位大佬的讲解
代码
#include<iostream>
using namespace std;
#define rl rt << 1
#define rr rt << 1 | 1
#define ms m = (tre[rt].l + tre[rt].r) >> 1
const int maxn = 300005;
struct Node
{
int l, r, mn, lazy;
} tre[maxn << 2];
int p[maxn];
void Push_up(int rt)
{
tre[rt].mn = min(tre[rl].mn, tre[rr].mn);
}
void Push_down(int rt)
{
int ly = tre[rt].lazy;
if(ly) //如果 lazy 不等于0,我们要下推标记
{
tre[rl].lazy += ly;
tre[rl].mn += ly;
tre[rr].lazy += ly;
tre[rr].mn += ly;
tre[rt].lazy = 0; //解除标记
}
}
void Build(int rt, int l, int r)
{
tre[rt].l = l, tre[rt].r = r;
tre[rt].mn = tre[rt].lazy = 0;
if(l == r) return;
int m = (l + r) >> 1;
Build(rl, l, m);
Build(rr, m + 1, r);
}
void Update(int rt, int s, int e, int val)
{
if(s <= tre[rt].l && tre[rt].r <= e)
{
tre[rt].mn += val;
tre[rt].lazy += val;
return;
}
Push_down(rt);
int ms;
if(s <= m) Update(rl, s, e, val);
if(e > m) Update(rr, s, e, val);
Push_up(rt);
}
int main()
{
/* freopen("A.txt","r",stdin); */
/* freopen("Ans.txt","w",stdout); */
int n;
scanf("%d", &n);
int x;
for(int i = 1; i <= n; i ++)
scanf("%d", &x), p[x] = i; //存储x这个值所在的位置为 i
Build(1, 1, n);
int ans = n + 1;
int q;
for(int i = 1; i <= n; i ++)
{
scanf("%d", &q);
while(tre[1].mn >= 0) //当tre[1].mn 小于0的时候我们可以确定当前最大值ans没有被没有被当前位置之前的所有炸弹炸掉,所以 最大值还是ans,直接输出就行了;
//如果tre[1].mn >= 0 这个时候 ans 这个序列中的最大值已经被 炸弹炸掉了,所以我们需要 while循环,找符合题意的ans使tre[rt].mn再次小于0,然后再次输出ans
{
ans --;
Update(1, 1, p[ans], -1);
}
Update(1, 1, q, 1);
printf("%d ", ans);
}
return 0;
}
Codeforces Global Round 7的更多相关文章
- CodeForces Global Round 1
CodeForces Global Round 1 CF新的比赛呢(虽然没啥区别)!这种报名的人多的比赛涨分是真的快.... 所以就写下题解吧. A. Parity 太简单了,随便模拟一下就完了. B ...
- Codeforces Global Round 1 - D. Jongmah(动态规划)
Problem Codeforces Global Round 1 - D. Jongmah Time Limit: 3000 mSec Problem Description Input Out ...
- Codeforces Global Round 2 题解
Codeforces Global Round 2 题目链接:https://codeforces.com/contest/1119 A. Ilya and a Colorful Walk 题意: 给 ...
- Codeforces Global Round 1 (A-E题解)
Codeforces Global Round 1 题目链接:https://codeforces.com/contest/1110 A. Parity 题意: 给出{ak},b,k,判断a1*b^( ...
- Codeforces Global Round 3
Codeforces Global Round 3 A. Another One Bites The Dust 有若干个a,有若干个b,有若干个ab.你现在要把这些串拼成一个串,使得任意两个相邻的位置 ...
- Codeforces Global Round 1 (CF1110) (未完结,只有 A-F)
Codeforces Global Round 1 (CF1110) 继续补题.因为看见同学打了这场,而且涨分还不错,所以觉得这套题目可能会比较有意思. 因为下午要开学了,所以恐怕暂时不能把这套题目补 ...
- 【手抖康复训练1 】Codeforces Global Round 6
[手抖康复训练1 ]Codeforces Global Round 6 总结:不想复习随意打的一场,比赛开始就是熟悉的N分钟进不去时间,2333,太久没写题的后果就是:A 题手抖过不了样例 B题秒出思 ...
- Codeforces Global Round 11 个人题解(B题)
Codeforces Global Round 11 1427A. Avoiding Zero 题目链接:click here 待补 1427B. Chess Cheater 题目链接:click h ...
- 【Codeforces Round 1110】Codeforces Global Round 1
Codeforces Round 1110 这场比赛只做了\(A\).\(B\).\(C\),排名\(905\),不好. 主要的问题在\(D\)题上,有\(505\)人做出,但我没做出来. 考虑的时候 ...
- 树形DP ---- Codeforces Global Round 2 F. Niyaz and Small Degrees引发的一场血案
Aspirations:没有结果,没有成绩,acm是否有意义?它最大的意义就是让我培养快速理解和应用一个个未知知识点的能力. ————————————————————————————————————— ...
随机推荐
- 选择结构二switch选择结构
在上一章节我们讲解了if选择结构 本章我们学习 switch选择结构 还要知道if选择结构和switch结构的区别 为什么学习了if选择结构还要学习switch选择结构 以及 两种选择结构的运用 ...
- 2020ubuntu1804server编译安装redis5笔记(二)配置redis
前一篇笔记记录了ubuntu1804server编译安装redis5,接下来要配置redis5了 网址:https://www.cnblogs.com/qumogu/p/12435694.html 第 ...
- Fabric 源码学习:如何实现批量管理远程服务器?
前不久,我写了一篇<Fabric教程>,简单来说,它是一个用 Python 开发的轻量级的远程系统管理工具,在远程登录服务器.执行 Shell 命令.批量管理服务器.远程部署等场景中,十分 ...
- Fortify Audit Workbench 笔记 Access Control: Database
Abstract 如果没有适当的 access control,就会执行一个包含用户控制主键的 SQL 指令,从而允许攻击者访问未经授权的记录. Explanation Database access ...
- requests.exceptions.SSLError报错
requests.exceptions.SSLError: HTTPSConnectionPool(host='www.baidu.com', port=443): Max retries excee ...
- Ubuntu16.04 desktop 设置共享文件夹 -- 图形界面配置
1. 安装 安装samba 直接采用 Ubuntu16.04 desktop 里面的安装向导来完成: 选中需要共享的文件夹 -> 右键 “local Network Share” -> 安 ...
- 【5min+】 一个令牌走天下!.Net Core中的ChangeToken
系列介绍 [五分钟的dotnet]是一个利用您的碎片化时间来学习和丰富.net知识的博文系列.它所包含了.net体系中可能会涉及到的方方面面,比如C#的小细节,AspnetCore,微服务中的.net ...
- Java设计模式学习笔记三
工厂模式 简单工厂模式(不属于23种设计模式之一) 属于创建型模式,是工厂模式的一种.简单工厂模式是由一个工厂对象决定创建出哪一种产品类的实例.简单工厂模式是工厂模式家族中最简单实用的模式: 简单工厂 ...
- Java14来了!Switch竟如此简单?Lombok也不需要了?来使用Idea配置Java14的开发环境吧!
Java 14 在 2020.3.17 日发布正式版了,但现在很多公司还在使用 Java 7 或 Java 8,每当看到 Java 又发布新版本心里就慌得一匹.不过此版本并不是 LTS (长期支持版) ...
- AspNetCore3.1_Secutiry源码解析_4_Authentication_JwtBear
title: "AspNetCore3.1_Secutiry源码解析_4_Authentication_JwtBear" date: 2020-03-22T16:29:29+08: ...