Educational Codeforces Round 58 (Rated for Div. 2) 题解
Educational Codeforces Round 58 (Rated for Div. 2)
题目总链接:https://codeforces.com/contest/1101
A. Minimum Integer
题意:
多组数据,给你三个数l,r,d,要求在区间[l,r]之外找一个最小的x,使得x%d==0。
题解:
当d<l or d>r的时候,直接输出d就好了。
当l<=d<=r的时候,找到最小的t,使得t*d>r就行了。
具体操作见代码:
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- int q;
- ll l,r,d;
- int main(){
- cin>>q;
- while(q--){
- cin>>l>>r>>d;
- if(d<l || d>r) cout<<d<<endl;
- else{
- ll now = r/d;
- cout<<(now+)*d<<endl;
- }
- }
- return ;
- }
B. Accordion
题意:
给出一个字符串,要求删去一些数后它由以下几个部分组成,[ : .... : ],这其中"...."指的是0个或多个“ | ”。
问满足上面条件时,留下的字符串的最大长度为多少。
题解:
模拟一下就好了,从左往右遍历找 [ 以及 :
然后再从右往左遍历找 ] 以及 :
最后找中间的 |
这只是大体思路,代码还需要判断这些是否存在(我就是没判断这个被hack了...)、是否满足条件。
代码如下:
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N = 5e5+;
- char s[N];
- int main(){
- scanf("%s",s);
- int len = strlen(s);
- int j=len,ans=;
- for(int i=;i<len;i++){
- if(j==len){
- if(s[i]=='[') ans++,j--;
- continue ;
- }else if(j==len-){
- if(s[i]==':'){
- ans++;
- j=i;
- break ;
- }
- }
- }
- int k=;
- for(int i=len-;i>=;i--){
- if(k==){
- if(s[i]==']') ans++,k++;
- continue ;
- }else if(k==){
- if(s[i]==':'){
- ans++;
- k=i;
- break ;
- }
- }
- }
- if(j>=k) puts("-1");
- else{
- for(int i=j+;i<k;i++){
- if(s[i]=='|') ans++;
- }
- cout<<ans<<endl;
- }
- return ;
- }
C. Division and Union
题意:
给出n个区间,然后将这些区间分到两个集合S1,S2中,要求S1与S2的交集为空。最后输出区间是属于1集合还是2集合。
题解:
一开始想歪了,用并查集去做,虽然也可以做,但是有点麻烦了。
分析一下就可以发现,相交的区间肯定放在一个集合中,不相交的区间可以放在一个集合中,也可以放在另外一个集合中。
那么我们直接按左端点排序后,贪心地将前n-1个区间放在一个集合中,判断第n个区间放入另一个集合是否满足条件就ok了。
注意的是放入一个集合的时候,需要维护右端点的最大值,这样最后比较的时候才能保证正确性。
代码如下:
- #include<bits/stdc++.h>
- #define INF 0x3f3f3f3f
- using namespace std;
- typedef long long ll;
- const int N = 2e5+;
- int n;
- struct Seg{
- int l,r,id;
- bool operator < (const Seg &A)const{
- return l<A.l;
- }
- }seg[N];
- int T;
- int ans[N],a[N];
- int main(){
- cin>>T;
- while(T--){
- scanf("%d",&n);
- for(int i=;i<=n;i++){
- scanf("%d%d",&seg[i].l,&seg[i].r);
- seg[i].id=i;
- a[i]=;
- }
- sort(seg+,seg+n+);
- int t=;
- int max_r = ;
- a[]=;
- for(int i=;i<n;i++){
- max_r = max(max_r,seg[i].r);
- if(!a[i]) a[i]=a[i-];
- if(max_r<seg[i+].l){
- t++;
- a[i+]=t;
- }
- }
- if(!a[n]) a[n]=a[n-];
- if(t<) puts("-1");
- else{
- for(int i=;i<=n;i++){
- if(a[i]<t) ans[seg[i].id]=;
- else ans[seg[i].id]=;
- }
- for(int i=;i<=n;i++) printf("%d ",ans[i]);
- printf("\n");
- }
- }
- return ;
- }
D. GCD Counting
题意:
给出一颗树,每个结点有相应的权值,现在定义g(x,y)为树上x到y的简单路径的所有结点权值的最大公约数,dis(x,y)为x到y路径上面点的个数。求最大的dis(x,y)且满足g(x,y)>1。
题解:
说说比较朴素的方法吧...虽然速度比较慢,但对于我这种蒟蒻比较好懂...
对于2到2e5中的每个数,找出以其为因子的所有点,这些点不一定是连通的,最终呈现出来的应该是多个连通块。
然后我们直接对每个点跑最大直径就行了。
这个算法的具体时间复杂度我也不太清楚,但应该比较高,有方法可以将算法优化到nlogn的级别...
代码如下:
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N = 2e5+;
- int a[N],vis[N];
- int ans,n;
- vector <int> g[N],vec[N];
- int dfs(int u){
- vis[u]=;
- int mx = ;
- for(int v:g[u]){
- if(vis[v]){
- int now = dfs(v);
- ans = max(ans,now++mx);
- mx = max(mx,now);
- }
- }
- ans=max(ans,);
- return mx+;
- }
- int main(){
- scanf("%d",&n);
- for(int i=;i<=n;i++){
- scanf("%d",&a[i]);
- for(int j=;j*j<=a[i];j++){
- if(a[i]%j) continue ;
- vec[j].push_back(i);
- if(j*j!=a[i]) vec[a[i]/j].push_back(i);
- }
- }
- for(int i=;i<n;i++){
- int u,v;
- scanf("%d%d",&u,&v);
- g[u].push_back(v);
- g[v].push_back(u);
- }
- for(int i=;i<=2e5;i++){
- for(int v:vec[i]) vis[v]=;
- for(int u:vec[i]) if(vis[u]) dfs(u);
- }
- printf("%d",ans);
- return ;
- }
E. Polycarp's New Job
题意:
在线给出一些矩形的长和宽,以及在线询问:给出一个矩形的箱子,问能否将之前所有给出的矩形装进去。
题解:
这是E题的难度么...感觉比C题还简单点。
对于给出的长和宽,让短边在前,长边在后。然后维护最长短边以及最长长边就行了。因为我们放的时候的最优选择肯定是短边放短边的。
最后询问的时候判断下就ok了...
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N = 5e5+;
- int n;
- int main(){
- cin>>n;
- int l = ,r = ;
- getchar();
- while(n--){
- char c;
- int x,y;
- scanf("%c %d %d",&c,&x,&y);
- if(x>y) swap(x,y);
- if(c=='+'){
- l=max(l,x);
- r=max(r,y);
- }else{
- if(x<l || y<r) puts("NO");
- else puts("YES");
- }
- getchar();
- }
- return ;
- }
G. (Zero XOR Subset)-less
题意:
给出n个数,要求尽量多地将这些数划分为连续地几段,并且满足任意子集地异或和不为0。
题解:
只要所有数的异或和都不为0,那么就必然存在一种划分方法,通过这个可以判断可行性。
根据异或的性质,考虑异或前缀和,那么任意一段数的异或和都可以用两个前缀和异或来表示。
现在问题就转化为了:在n个数中选取尽量多的数,使得这些数的任意子集的异或和不为0。
这是个线性基的经典问题,关于线性基,可以参考下这篇博客:https://www.cnblogs.com/ljh2000-jump/p/5869991.html
线性基有几个性质,其中包括:一是线性基的任意子集异或和都不为0;二是线性基的任意子集异或和的值域等于原数的任意子集异或和的值域。
那么,最终的答案就是前缀异或和中线性基的个数。
代码如下:
- #include <bits/stdc++.h>
- using namespace std;
- typedef long long ll;
- const int N = 2e5+;
- int a[N],p[N],sum[N];
- int n;
- int main(){
- scanf("%d",&n);
- for(int i=;i<=n;i++){
- scanf("%d",&a[i]);
- sum[i]=sum[i-]^a[i];
- }
- if(!sum[n]){
- cout<<-;
- return ;
- }
- for(int i=;i<=n;i++){
- for(int j=;j>=;j--){
- if(!((<<j)&sum[i])) continue ;
- if(!p[j]){
- p[j]=sum[i];
- break ;
- }
- sum[i]^=p[j];
- }
- }
- int ans = ;
- for(int i=;i<;i++) if(p[i]) ans++;
- cout<<ans;
- return ;
- }
Educational Codeforces Round 58 (Rated for Div. 2) 题解的更多相关文章
- Educational Codeforces Round 63 (Rated for Div. 2) 题解
Educational Codeforces Round 63 (Rated for Div. 2)题解 题目链接 A. Reverse a Substring 给出一个字符串,现在可以对这个字符串进 ...
- Educational Codeforces Round 65 (Rated for Div. 2)题解
Educational Codeforces Round 65 (Rated for Div. 2)题解 题目链接 A. Telephone Number 水题,代码如下: Code #include ...
- Educational Codeforces Round 64 (Rated for Div. 2)题解
Educational Codeforces Round 64 (Rated for Div. 2)题解 题目链接 A. Inscribed Figures 水题,但是坑了很多人.需要注意以下就是正方 ...
- Educational Codeforces Round 60 (Rated for Div. 2) 题解
Educational Codeforces Round 60 (Rated for Div. 2) 题目链接:https://codeforces.com/contest/1117 A. Best ...
- Educational Codeforces Round 58 (Rated for Div. 2) F dp + 优化(新坑) + 离线处理
https://codeforces.com/contest/1101/problem/F 题意 有n个城市,m辆卡车,每辆卡车有起点\(s_i\),终点\(f_i\),每公里油耗\(c_i\),可加 ...
- Educational Codeforces Round 58 (Rated for Div. 2) D 树形dp + 数学
https://codeforces.com/contest/1101/problem/D 题意 一颗n个点的树,找出一条gcd>1的最长链,输出长度 题解 容易想到从自底向长转移 因为只需要g ...
- Educational Codeforces Round 58 (Rated for Div. 2) G 线性基
https://codeforces.com/contest/1101/problem/G 题意 一个有n个数字的数组a[],将区间分成尽可能多段,使得段之间的相互组合异或和不等于零 题解 根据线性基 ...
- Educational Codeforces Round 58 (Rated for Div. 2)
A. Minimum Integer 水 #include<bits/stdc++.h> #define clr(a,b) memset(a,b,sizeof(a)) using name ...
- Educational Codeforces Round 58 (Rated for Div. 2) (前两题题解)
感慨 这次比较昏迷最近算法有点飘,都在玩pygame...做出第一题让人hack了,第二题还昏迷想错了 A Minimum Integer(数学) 水题,上来就能做出来但是让人hack成了tle,所以 ...
随机推荐
- python学习之常用模块
- ecshop漏洞修复 以及如何加固ecshop网站安全?
由于8月份的ECSHOP通杀漏洞被国内安全厂商爆出后,众多使用ecshop程序源码的用户大面积的受到了网站被篡改,最明显的就是外贸站点被跳转到一些仿冒的网站上去,导致在谷歌的用户订单量迅速下降,从百度 ...
- Leecode刷题之旅-C语言/python-20.有效的括号
/* * @lc app=leetcode.cn id=20 lang=c * * [20] 有效的括号 * * https://leetcode-cn.com/problems/valid-pare ...
- EXKMP学习笔记QAQ
因为一本通少了一些算法,所以我就自行补充了一些东西上去. EXKMP也就是扩展KMP,是一种特别毒瘤的东西 EXKMP确实很难,我理解他的时间与AC机的时间差不多,而且还很难记,因此一学会就马上写博客 ...
- STL——list
1.关键概述 list 是定义在 namespace::std 的模板,声明在 <list> ,存储结构是 双向链表, 提供的 正向和反向迭代器. 2.构造list对象 list<i ...
- (数据科学学习手札11)K-means聚类法的原理简介&Python与R实现
kmeans法(K均值法)是麦奎因提出的,这种算法的基本思想是将每一个样本分配给最靠近中心(均值)的类中,具体的算法至少包括以下三个步骤: 1.将所有的样品分成k个初始类: 2.通过欧氏距离将某个样品 ...
- cadence17.2的OrCAD启动找不到license的问题
1. cadence17.2的OrCAD每次启动都说找不到license 2. 提示是找不到licence,看下系统变量,licence的路径是在的 3. 估计是读取licence的路径的服务未开启, ...
- 基于jersey和Apache Tomcat构建Restful Web服务(二)
基于jersey和Apache Tomcat构建Restful Web服务(二) 上篇博客介绍了REST以及Jersey并使用其搭建了一个简单的“Hello World”,那么本次呢,再来点有趣的东西 ...
- Linux下创建pycharm的快捷方式
第一步:创建桌面快捷方式文件Pycharm.desktop,并打开 sudo gedit /usr/share/applications/Pycharm.desktop 第二步:在打开的文件Pycha ...
- 自动化测试学习之路--java String、StringBuilder
Java中的String和StringBuilder类: 1.String对象是不可变的.每一个看起来修改了String值的方法,实际上都是创建了全新的String对象.代码示例如下: String ...