Codeforces Round #674 (Div. 3)A-F题解

比赛链接:https://codeforces.com/contest/1426

A题
水题不写题解

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;int32_t main()
{IOS;int t;cin>>t;while(t--){int n,x;cin>>n>>x;if(n<3) cout<<1<<endl;else cout<<(n-2)/x+((n-2)%x?1:0)+1<<endl;}
}

B题
简单构造

题意为给定n个2 ×\times× 2的矩阵,你可以使用任意次这些矩阵,要求拼出一个m ×\times× m的按照主对角线对称的矩阵。询问是否可以构造。

根据矩阵是否在主对角线上,我们可以注意到在对角线上的2 ×\times× 2 矩阵也同时需要按照自己的主对角线对称,而不主对角线上的矩阵,两两之间需要互相对称,我们不难发现如果有满足主对角线上矩阵条件的2 ×\times× 2 矩阵,那我们把这些矩阵直接铺满非对角线的部分也是满足要求的。

因此直接判断给的2 ×\times× 2 矩阵中是否存在自身就是个关于主对角线对称的矩阵即可,同时m需要满足是一个偶数。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;int num[107][2][2];int32_t main()
{IOS;int t;cin>>t;while(t--){int n,m;cin>>n>>m;bool flag=0;for(int i=0;i<n;i++){for(int j=0;j<2;j++)for(int k=0;k<2;k++)cin>>num[i][j][k];if(num[i][0][1]==num[i][1][0]) flag=1;}if(m%2==0&&flag) cout<<"YES"<<endl;else cout<<"NO"<<endl;}
}

C题
简单构造,暴力或简单结论

题意为一开始的时候数列只有一个数字1,每次操作你可以对数列中的一个数字加1,或者复制某一个数字到数列末尾,问你最少需要多少次操作可以使得这个数列中所有数的值加起来不小于n。

我们注意到每次操作,
如果选择值+1的话只会对整体产生+1的影响,但是这个+1后的值会增加复制操作可增加的最大值。
而复制某一个值会增加一个当前最大的数的值,但是不会对后续操作可增加的最大值产生影响。

我们直接贪心选择先不断对第一个数+1,+1到合适大小后不断复制这个值即可。
假设我们先+1到值为i,那么总的操作次数分为两个部分,第一个部分是+1的次数为i-1,第二个部分是复制数值i的次数,为n/i-1+n%i?1:0。
推到这里之后直接暴力for sqrt(n)已经可以过题。
但是还可以简单地再深入一下,我们对i增加1,会对第一部分的操作次数i-1产生+1的影响,那么在第二部分的n/i-1+n%i?1:0的部分至少要减去1,我们对i的+1操作才是正面的。写过《算竞》上余数之和这个例题可能会比较敏感,或者自己稿纸上写一下也能发现这个规律,此时i的值取sqrt(n)就是最优。当i>=sqrt(n)时,当i变化时,n/i的步长变化不可能大于1,与i<sqrt(n)的情况反过来对应。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;int32_t main()
{IOS;int t;cin>>t;while(t--){ll n;cin>>n;ll temp=sqrt(n);cout<<temp-1+n/temp-1+(n%temp?1:0)<<endl;}
}

D题
贪心,构造

题意为给定一个数列,不包含0,现在问你最少需要往这个数列中插入几个数字,使得这个数列不存在某个连续的区间的数值和为0。

这里直接采取贪心的策略就是了,从左往右扫过去,对于第一段出现的和为0的区间,我们必定要在中间插入一个数字,可以直接贪心在最右边的一个元素的左侧插入一个“无穷大”的值,这样的话,这个无穷大值左侧的部分都不会和右侧的部分加起来等于0了。

这里区间为0可以用map记录前缀和的出现情况来处理,每次出现某个区间和为0后,插入次数+1并把map清零,记录当前位置的值到map里。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;int32_t main()
{IOS;ll n,sum=0,ans=0;cin>>n;map<ll,bool>M;//M[x]记录前缀合x是否在前面出现过,如果当前前缀和为x,那么在当前位置到之前记录x的位置之间的数加起来为0M[0]=1;//0要初始化为出现过,意思为开头到目前为止所有部分的值加起来为0for(int i=0;i<n;i++){ll x;cin>>x;sum+=x;if(M.find(sum)!=M.end())//如果当前前缀和和之前某个位置的相同,代表这两个位置间(包括当前位置)的值加起来为0{//贪心过程在当前位置前的一个位置塞入一个绝对值足够大的数字即可M.clear();sum=x;//当前前缀合变为刚读入的这个数,前面的数字不再对后续产生影响,可以理解为我们在前面一个位置插入了一个无穷大M[x]=M[0]=1;ans++;}else M[sum]=1;}cout<<ans<<endl;
}

E题
贪心,小结论,暴力

两个人进行n轮石头剪刀布,每个人准备出几次剪刀,几次石头,几次布都已经给出,要求求出第一个人最少和最多能获得的胜场数。

最多能获得的胜场数很容易贪心得到,直接第一个人的剪刀和第二个人的布的场次取较小值加到答案上,另外两种情况也相同。

最少能获得的胜场数需要做个小结论,我们可以反过来思考,我们要获得最少的胜场数,也就等同于要得到最多的平局和负场数。而平局和负场的话,剪刀可以与剪刀构成平局,也可以去和石头构成负场。
我们优先考虑平局,再在这里我人为规定一个词叫做“被挤占”的状态,比如说1次第一个人的剪刀我们安排和第二个人的石头对应,1次第一个人的石头本来应当和第二个人的石头对应,现在“被挤占”后被迫和布对应。
如果剪刀石头布都存在“被挤占”的状态的话,不难发现构成了一个三场都负的循环,我们完全可以让他们变成三场都平局,排除这三个“被挤占”的状态。从而可以得到结论,最优的那种情况,必然可以转化为剪刀石头布中有一个不存在“被挤占”状态的方案,也就是优先考虑三种出法某一种。
由此我们直接for个3遍,优先考虑三种出法能获得的平局和负场数,取最大后被减去便是答案。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;ll a[3],b[3];int32_t main()
{IOS;ll n;cin>>n;cin>>a[0]>>a[1]>>a[2];cin>>b[0]>>b[1]>>b[2];ll ans=0;//记录最高可以得到的负场和平局数量for(int i=0;i<3;i++)//优先考虑a中的哪一个{ll now=0,sum=0;//now记录位置有多少场次需要寻找平局和负场,sum为优先考虑a[i]的情况下得到的负场和平局数for(int j=0;j<3;j++){int tar=(i-j+3)%3;//寻找当前位置的下标,现在是尽可能多的寻找平局和负场ll temp=b[tar];sum+=min(now,temp);temp-=min(now,temp);//上一个位置留下的部分可以在当前位置放now=a[tar];//放置后上一个位置的场次没被安排的无法保存到下一个,直接清零记录为当前位置的场次即可sum+=min(now,temp);now-=min(now,temp);//当前位置b仍然能安排的优先安排}ans=max(ans,sum);}cout<<n-ans<<' ';ans=0;for(int i=0;i<3;i++) ans+=min(a[i],b[(i+1)%3]);cout<<ans<<endl;
}

F题
dp

题意为给定一个字符串,只包含abc?四种字符,其中?字符可以用abc任意一个去替换,问将所有的?替换后的所有字符串中,子串abc(下标不一定连续)总共出现了几次。

我们注意到,我们如果从左往右看过去的话,我们实际上需要关注的,只是a,ab,abc出现了几次。那么我们可以根据第i个位置是a,b,c做一个3 ×\times× n 的线性dp。
首先当前位置的情况,要继承上个位置所有构造方案的情况(见trans函数)。之后根据当前位置构造是a还是b还是c进行三种不同的转换。
如果构造a的话,只会对a的数量产生影响,当前位置之前出现了x个问号,那么此时前面共有3x种构造方法,每种方法都会增加一个a。因此直接增加3x个a。
如果构造b的话,只会对ab的数量产生影响,增加前面一个位置下记录的所有a的个数即可。
如果构造c的话,只会对abc的数量产生影响,增加前面一个位置下记录的所有ab的个数即可。

#include<bits/stdc++.h>
#define ll long long
#define llINF 9223372036854775807
#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
using namespace std;
const ll mod=1e9+7;
const ll maxn=2e5+7;struct Node
{ll a,ab,abc;
};Node dp[maxn][3];//dp[i][j]表示第i个字符构造j的情况下,a/ab/abc各自出现了几次,j=0代表构造字符'a',j=1代表构造'b',j=2代表构造'c'
//当s[i]是个确定的字符时,只转移到dp[i][0]上
int n;
ll cas=1;//记录3^k,用于构造'a'时的转移
char s[maxn];void trans(int x,int y)
{for(int i=0;i<3;i++){dp[x][y].a=(dp[x][y].a+dp[x-1][i].a)%mod;dp[x][y].ab=(dp[x][y].ab+dp[x-1][i].ab)%mod;dp[x][y].abc=(dp[x][y].abc+dp[x-1][i].abc)%mod;}
}void transa(int x,int y)//构造a时的转移方式
{trans(x,y);dp[x][y].a=(dp[x][y].a+cas)%mod;
}void transb(int x,int y)//构造b时的转移方式
{trans(x,y);dp[x][y].ab=(dp[x][y].ab+dp[x-1][0].a+dp[x-1][1].a+dp[x-1][2].a)%mod;
}void transc(int x,int y)//构造c时的转移方式
{trans(x,y);dp[x][y].abc=(dp[x][y].abc+dp[x-1][0].ab+dp[x-1][1].ab+dp[x-1][2].ab)%mod;
}int32_t main()
{IOS;cin>>n>>(s+1);for(int i=1;i<=n;i++){if(s[i]=='?'){transa(i,0);transb(i,1);transc(i,2);cas=cas*3%mod;}else{if(s[i]=='a') transa(i,0);if(s[i]=='b') transb(i,0);if(s[i]=='c') transc(i,0);}}cout<<(dp[n][0].abc+dp[n][1].abc+dp[n][2].abc)%mod<<endl;
}

Codeforces Round #674 (Div. 3)A-F题解相关推荐

  1. Educational Codeforces Round 110 div.2 A~F题解

    视频讲解:BV1254y137Rn A. Fair Playoff 题目大意 有 444 位选手参加比赛,第 iii 位选手的水平为 si(1≤si≤100)s_i(1 \leq s_i \leq 1 ...

  2. Codeforces Round #674 (Div. 3) F. Number of Subsequences 简单计数dp

    传送门 文章目录 题意: 思路: 题意: 给你一个长度为nnn的串,包含a,b,c,?a,b,c,?a,b,c,?四种字符,其中???可以变成为a,b,ca,b,ca,b,c的任意一种,让你求abca ...

  3. Codeforces Round #797 (Div. 3)无F

    Codeforces Round #797 (Div. 3)无F 这打的也太屎了,白天把G补了才知道简单的很,但f还是没头绪呜呜呜 Problem - A - Codeforces Given the ...

  4. Codeforces Round #701 (Div. 2) A ~ F ,6题全,超高质量良心题解【每日亿题】2021/2/13

    整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A - Add and Divide B - Replace and Keep Sorted C ...

  5. Codeforces Round #774 (Div. 2)E题题解

    Codeforces Round #774 (Div. 2) E. Power Board 题目陈述 有一个n×m(1≤n,m≤106)n\times m(1\le n,m\le10^6)n×m(1≤ ...

  6. Codeforces Round #198 (Div. 2)A,B题解

    Codeforces Round #198 (Div. 2) 昨天看到奋斗群的群赛,好奇的去做了一下, 大概花了3个小时Ak,我大概可以退役了吧 那下面来稍微总结一下 A. The Wall Iahu ...

  7. Codeforces Round #640 (Div. 4)(ABCDEG题解)

    文章目录 A. Sum of Round Numbers B - Same Parity Summands C - K-th Not Divisible by n D - Alice, Bob and ...

  8. Codeforces Round #635 (Div. 2)(A~D)题解

    Codeforces #635 A~D A.Ichihime and Triangle B.Kana and Dragon Quest game C.Linova and Kingdom D.Xeni ...

  9. Codeforces Round #641 (Div. 2)A~E题解(数论场)

    题目大意就是给你一个数执行k次操作,每次加上这个数的最小质因子(除了一以外)变成一个新的数,问最后的数是多少 解题思路:很明显如果一开始是偶数的话就会一直加2加2,如果是奇数的话先找到这个数的质因子一 ...

最新文章

  1. Struts2 校验数据问题
  2. 信用评分python_信用评分卡(python)
  3. python实时读取日志并打印关键字怎么实现_python pytest测试框架介绍五---日志实时输出...
  4. nginx配置静态资源允许跨域访问
  5. 让计算机教育因云而变,阿里云正式发布云原生人才培养合作计划
  6. 价值连城 知名深度强化学习Pieter Abbeel的采访 给机器学习 深度学习 和机器人学研究者从业者的建议
  7. 2021WordPress转z-blog搬家教程_WordPress搬家zblog博客程序工具
  8. 快速了解FTTx/FTTC/FTTB/FTTH
  9. iOS 5 故事板进阶(4)
  10. 《大数据时代》读后感(一)
  11. NVIDIA显卡驱动及CUDA相关安装流程(包括多版本cuda切换)
  12. 卧槽!又来一个Python大数据学习神器!
  13. 硫化氢探针|H2S荧光探针|hydrogen sulfide荧光探针的结构式
  14. win10计算机管理器在哪,Windows10开启服务管理器图文教程|Win10系统服务管理器在哪...
  15. 【产品】OEM、ODM、OBM是什么?
  16. 【计算机网络】B类IP地址
  17. ssh连接服务器失败解决记录
  18. TLE7244SL-ASEMI代理英飞原装汽车芯片TLE7244SL
  19. 物联网导论课设作业安全系统的代码
  20. 5g/4g边缘计算网关

热门文章

  1. 指纹识别(一)—— 电容式、光学式、超声波式介绍
  2. c语言变量名、函数名的命名规则
  3. 手动释放定时释放Linux的buff/cache内存
  4. 【数据集处理】Python修改图片为.jpg格式批量修改名字为000000格式
  5. iOS视频裁剪小工具——VideoTailor
  6. vivoy66升级Android+7.,vivoy66和X7哪个值得买?vivoy66与x7详细区别对比评测
  7. MySQL 面试题(一):索引失效的几种情况
  8. go分割字符串,按照多个字符分割。
  9. [转]MySQL锁机制,行锁竟然加在索引上!!!
  10. 基于android智能手机的隐私管理系统的设计与实现,基于Android的智能手机求助系统的设计与实现...