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是否有意义?它最大的意义就是让我培养快速理解和应用一个个未知知识点的能力. ————————————————————————————————————— ...
 
随机推荐
- C# 视频监控系统(提供源码分享)
			
去过工厂或者仓库的都知道,在工厂或仓库里面,会有很多不同的流水线,大部分的工厂或仓库,都会在不同流水线的不同工位旁边安装一台电脑,一方面便于工位上的师傅把产品的重要信息录入系统,便于公司系统数据采集分 ...
 - 本地目录配置多个远程Git仓库
			
目录 情景一:不同的库分别 pull/push 1. 使用git命令配置 2. 修改.git/config 文件 3. 操作 情景二:不同的库一次push 1. 使用git命令配置 2. 修改.git ...
 - 安装docker,docker-compose,Harbor
			
一.docker安装 1.删除旧版本和相关依赖 yum remove docker \ docker-client \ docker-client-latest \ docker-common \ d ...
 - Nginx之负载均衡配置(一)
			
前文我们聊了下nginx作为反向代理服务器,代理后端动态应用服务器的配置,回顾请参考https://www.cnblogs.com/qiuhom-1874/p/12430543.html:今天我们来聊 ...
 - AppBoxFuture实战: 如何同步开发与生产环境的模型
			
框架是用抽象模型驱动的方式来生成应用系统的,这样可以将这些模型序列化为相应的模型包文件,通过反序列化导入至其他部署环境内,从而实现开发环境与生产环境的同步,包括对应的数据库结构的同步.下面通过示例 ...
 - 【BIM】BIMFACE中创建矢量文本
			
背景 在三维模型产品的设计中,针对空间的管理存在这样一个普遍的需求,那就是在三维模型中,将模型所代表的空间通过附加文本的方式来展示其所代表的实际位置或功能,之前尝试过若干方式,比如直接在建模的时候,将 ...
 - 原生js实现随着滚动条滚动,导航会自动切换的效果
			
最近学习前端,把前面用原生js写的一段有关tab切换效果的代码贴上,实现的效果比较简陋,请大家见谅 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1 ...
 - 死磕Lambda表达式(三):更简洁的Lambda
			
我们都是阴沟里的虫子,但总还是得有人仰望星空.--<三体> 在之前的文章中介绍了Lambda表达式的基本语法和正确使用姿势,这次我来介绍一些Lambda更简洁的用法. 欢迎关注微信公众号: ...
 - Java多线程并发02——线程的生命周期与常用方法,你都掌握了吗
			
在上一章,为大家介绍了线程的一些基础知识,线程的创建与终止.本期将为各位带来线程的生命周期与常用方法.关注我的公众号「Java面典」了解更多 Java 相关知识点. 线程生命周期 一个线程不是被创建了 ...
 - ElasticSearch之映射常用操作
			
本文案例操作,建议先阅读我之前的文章<ElasticSearch之安装及基本操作API> Mapping (映射)类似关系型数据库中的表的结构定义.我们将数据以 JSON 格式存入到 El ...