Codeforces Round #470 (rated, Div. 2, based on VK Cup 2018 Round 1) 题解

本文提供了CodeForces 948比赛的五道题目的详细解答过程及思路,包括保护羊群、质数游戏、造雪、完美安全及字符串选择等问题。

比赛链接:http://codeforces.com/contest/948
A. Protect Sheep
题意:给了一个n*m的图,其中.代表空地,S代表羊,W代表狼,D代表狗,羊和狗都不能动,只有狼可以冻,现在狗有无限多个,如果通过给地图放狗可以保护所有的羊都不被吃,那就输出放狗之后的图,如果通过放狗还可以使狼吃羊,那么就输出No。
解法:我们只需要判断每一只羊的上下左右没有狼就好,如果都没有狼,那么一定可以保护,直接在所有的羊周围放狗即可

#include <bits/stdc++.h>
using namespace std;
const int maxn = 505;
int n,m;
char maze[maxn][maxn];
int dir[4][2]={{0,1},{0,-1},{1,0},{-1,0}};
bool check(int x,int y){
    if(x>=0&&x<n&&y>=0&&y<m) return true;
    else return false;
}
int main(){
    scanf("%d%d",&n,&m);
    bool flag = true;
    for(int i=0; i<n; i++) scanf("%s", maze[i]);
    for(int i=0;i<n;i++){
        for(int j=0; j<m; j++){
            if(maze[i][j]=='S'){
                for(int k=0; k<4; k++){
                    int tx = i+dir[k][0];
                    int ty = j+dir[k][1];
                    if(check(tx,ty)&&maze[tx][ty]=='W'){
                        flag = false;
                    }
                }
            }
        }
    }
    if(flag){
        puts("Yes");
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
               if(maze[i][j]=='S'){
                for(int k=0;k<4;k++){
                    int tx=i+dir[k][0];
                    int ty=j+dir[k][1];
                    if(check(tx,ty)&&maze[tx][ty]=='.'){
                        maze[tx][ty]='D';
                    }
                }
               }
            }
        }
        for(int i=0;i<n;i++){
            printf("%s\n",maze[i]);
        }
    }else{
        puts("No");
    }
}

B. Primal Sport
题意:假设当前的数是x[i],那么x[i+1]由质数p(p

#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6+10;
int n, ans, f[maxn];
int main(){
    scanf("%d",&n);
    ans = n;
    for(int i=2; i<=n; i++){
        if(!f[i]){
            for(int j=2*i; j<=n; j+=i) f[j] = i;
        }
        f[i] = i-f[i]+1;
    }
    for(int i=f[n];i<=n;i++) ans = min(ans, f[i]);
    printf("%d\n", ans);
}

C. Producing Snow
题意:每天会有 ai 个雪球被创建 每天会有bi 个雪球会被融化掉 求每天的融化的 个数
解法:用multiset来搞。每个ai都会被插入multiset,然后根据融化bi的累加值来判断multiset的哪些元素会被全部删除,然后删除之后再更新累加值,说的比较乱,希望代码可以看懂。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int maxn = 100010;
multiset <LL> s;
LL a[maxn], b[maxn];
int main(){
    LL n;
    scanf("%lld", &n);
    for(int i=1; i<=n; i++) scanf("%lld", &a[i]);
    for(int j=1; j<=n; j++) scanf("%lld", &b[j]);
    LL d = 0;
    LL add = 0;
    int k = 0;
    for(int i=1; i<=n; i++){
        s.insert(a[i]+add);
        d+=b[i];
        LL re = 0;
        while(s.size()&&*s.begin()-d<=0){
            re += *s.begin()-add;
            s.erase(s.begin());
            k++;
        }
        re += 1LL*(i-k)*b[i];
        add = d;
        printf("%lld ", re);
    }
    printf("\n");
}

D. Perfect Security
题意:可以任意打乱序列b的顺序和a挨着异或,求答案序列的字典序最小值。
解法:很水的一眼题,插入字典树,然后贪心。

#include <bits/stdc++.h>
using  namespace std;
int ch[9000010][2], num[9000010][2], a[300010], b[300010], p[300010], n, k;
void add(int u){
    int now = 0;
    for(int i=30; i>=0; i--){
        int t = (u>>i)&1;
        if(!ch[now][t]) ch[now][t]=++k;
        num[now][t]++;
        now=ch[now][t];
    }
}
int query(int u){
    int now=0,ans=0;
    for(int i=30;i>=0;i--){
        int t=(u>>i)&1;
        if(ch[now][t]&&num[now][t]) --num[now][t],now=ch[now][t];
        else --num[now][t^1], now=ch[now][t^1], ans+=(1<<i);
    }
    return ans;
}
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]), add(b[i]);
    for(int i=1;i<=n;i++) p[i] = query(a[i]);
    for(int i=1;i<=n;i++) printf("%d ", p[i]);
}

E:Picking String
题意:给出字符串S和T,1e5个询问,每次询问S的一段区间是否能转变成T的一段区间。 转变方式:A->BC,B->AC,C->AB。AAA可以消除。
解法:不会这题啊。。http://blog.csdn.net/weixin_37517391/article/details/79550785
B>AC>AAB>AAAC>C B − > A C − > A A B − > A A A C − > C
C>AB>AAC>AAAB>B C − > A B − > A A C − > A A A B − > B
A>BC>BB A − > B C − > B B
也就是说所有的C等价于B
由于B->AC也就是B->AB,而三个A可以消除,意思就是B前面可以有任意多个A,所以,B前面的紧贴着的A的数量我们可以忽略。
由于B->AB->BBB->ABBB->BBBBB,A->BB->ABB->BBBB也就是说,我们只要有一个A或者B就可以在这个基础上增加偶数个B。
那么问题就比较清楚了。但是T[c,d]串最后的A是一定要被S[a,b]最后的A抵消掉,因为没有操作可以生成A并且把A插入到S[a,b]的后面。
分为如下情况:
S[a,b]AT[a,b]A,0S[a,b]AT[a,b]A,delta2 如 果 S [ a , b ] 最 后 的 A 不 足 以 抵 消 掉 T [ a , b ] 的 A , 那 么 输 出 0 , 否 则 记 录 S [ a , b ] 后 面 的 A 与 T [ a , b ] 的 后 面 的 A 的 差 值 , 记 作 d e l t a 2
delta20S[a,b]BT[c,d]B2T[c,d]B0S[a,b]B0(BB) 如 果 d e l t a 2 等 于 0 , 那 么 只 需 要 比 较 S [ a , b ] 中 的 B 的 数 量 和 T [ c , d ] 中 的 B 的 数 量 , 那 么 差 值 必 定 要 为 2 的 倍 数 , 并 且 如 果 T [ c , d ] 中 B 的 数 量 不 为 0 , 那 么 S [ a , b ] 中 B 的 数 量 也 必 须 不 为 0 ( 无 法 从 空 串 生 成 B B ) 。
delta2>0S[a,b]BT[c,d]BS[a,b]ABBAB 如 果 d e l t a 2 > 0 那 么 如 果 S [ a , b ] 中 B 的 数 量 小 于 T [ c , d ] 中 B 的 数 量 , 并 且 差 值 为 偶 数 时 候 , S [ a , b ] 多 出 来 的 A 可 以 用 来 生 成 B B , 并 且 多 余 的 A 作 为 B 的 前 缀 可 以 被 消 除 掉 。
delta2>0S[a,b]BT[c,d]Bdelta23T 如 果 d e l t a 2 > 0 那 么 如 果 S [ a , b ] 中 B 的 数 量 等 于 T [ c , d ] 中 B 的 数 量 , 那 么 d e l t a 2 一 定 要 被 3 整 除 。 这 样 可 以 通 过 消 除 来 得 到 T

#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5+7;
char S[maxn], T[maxn];
int q,a,b,c,d;
int sumS[maxn], sumT[maxn];
int lastS[maxn], lastT[maxn];

int main(){
    scanf("%s %s %d", S,T,&q);
    for(int i=0; S[i]; i++){
        sumS[i+1] = sumS[i]+(S[i]=='C'||S[i]=='B');
        lastS[i+1] = lastS[i];
        if(S[i]=='B'||S[i]=='C') lastS[i+1]=i+1;
    }
    for(int i=0; T[i]; i++){
        sumT[i+1] = sumT[i]+(T[i]=='C'||T[i]=='B');
        lastT[i+1] = lastT[i];
        if(T[i]=='B'||T[i]=='C') lastT[i+1]=i+1;
    }
    while(q--){
        scanf("%d%d%d%d", &a,&b,&c,&d);
        int delta = sumT[d] - sumT[c-1] - (sumS[b]-sumS[a-1]);
        int delta2 = b-max(a-1,lastS[b]) - (d-max(c-1,lastT[d]));
        if(delta<0||delta%2!=0||delta2<0||delta2==0&&!(sumS[b]-sumS[a-1])&&delta>0){
            putchar('0');
            continue;
        }
        if(delta2==0||delta>0||delta2%3==0){
            putchar('1');
        }else{
            putchar('0');
        }
    }
    return 0;
}
内容概要:本文档是一份涵盖多个科研领域的Matlab、Python及Simulink代码实现资源集,重点包括通信系统中的GMSK调制二比特差分解调、Turbo码结合BPSK或GMSK的调制解调技术研究,以及永磁同步电机控制、微电网优化、路径规划、负荷预测、风电功率预测、无人机控制、电力系统仿真、信号处理、图像处理、雷达技术、车间调度、智能优化算法等多个方向的技术实现。文档详细列举了大量基于Matlab/Simulink的仿真项目,如自抗扰控制、模型预测控制、涡轮编码调制、智能优化算法等,并提供了相关代码资源的网盘链接。同时,文档强调科研过程中逻辑思维、创新意识与“借力”工具的重要性,倡导系统性学习与实践相结合,帮助研究者高效推进课题研究与论文复现工作。; 适合人群:具备一定Matlab、Python或Simulink编程基础,从事电子信息、通信工程、电气工程、自动化、控制科学与工程、电力系统、计算机科学等相关领域的研究生、科研人员及工程师,尤其适合开展仿真类课题或需要复现顶刊论文的研究者。; 使用场景及目标:① 学习和复现现代通信系统中GMSK、BPSK调制与Turbo码结合的仿真流程;② 掌握永磁同步电机控制策略(如自抗扰、滑模控制、模型预测控制)的建模与仿真方法;③ 实现微电网能量管理、路径规划、负荷预测、风电功率预测等复杂系统的算法开发与仿真验证;④ 辅助科研论文写作与课题研究,快速搭建仿真模型并优化算法性能;⑤ 借助智能优化算法解决生产调度、路径规划、资源配置等复杂工程问题。; 阅读建议:建议读者按照文档中项目分类循序渐进地学习,优先关注自身研究方向相关的代码实例。应结合理论知识,深入理解代码逻辑,并尝试在提供的仿真模型基础上进行参数调整与功能扩展,以达到掌握核心技术与提升科研效率的目标。注意资源来源于第三方,使用时需尊重版权,避免用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值