Codeforces Round #649 (Div. 2) C、Ehab and Prefix MEXs D、Ehab's Last Corollary 找环和点染色
题目链接:C、Ehab and Prefix MEXs
题意;
有长度为n的数组a(下标从1开始),要求构造一个相同长度的数组b,使得b1,b2,....bi集合中没有出现过的最小的数是ai.
mex函数表示不在集合中的那个最小的自然数
例如:
mex(1,2,3)=0
mex(0,1,2)=3
mex(0,1,3)=2
对于题意你要保证
mex(b1)=a1
mex(b1,b2)=a2
mex(b1,b2,b3)=a3
题解:
首先这个题目肯定是有解的,无解的情况题目都给排除了。
给b数组初始值为n+1,对于ai的值,我们必须保证0——(ai-1) (这代表区间【0,(ai-1)】)这些值都在b1——bi(这代表b1,b2...bi)出现过了。那么我们取b1——bi 中最小的不是n+1的值为x(如果全是n+1,那么x=0),我们从bi向b1逆向枚举,每遇到一个n+1,那就给它赋值x,然后让x++。这样一直操作就没了
至于为什么要逆向操作,这是个贪心,因为小的值ai只会在前面出现(题目要求了ai<=a(i+1)),如果你把小的值放在前面会影响前面答案的正确性
代码:
1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string>
5 #include<queue>
6 #include<string.h>
7 #include<map>
8 #include <iostream>
9 #include <math.h>
10 using namespace std;
11 typedef long long ll;
12 const int maxn=1e5+10;
13 int v[maxn],w[maxn];
14 int main()
15 {
16
17 int n;
18 scanf("%d",&n);
19 for(int i=1; i<=n; ++i)
20 {
21 scanf("%d",&v[i]);
22 w[i]=n+1;
23 }
24 int k=0;
25 for(int i=1; i<=n; ++i)
26 {
27 for(int j=i; j>=1; --j)
28 {
29 if(k>=v[i]) break;
30 if(w[j]==n+1)
31 {
32 w[j]=k++;
33 }
34 }
35 }
36 for(int i=1; i<=n; ++i)
37 {
38 if(i==n)
39 printf("%d\n",w[n]);
40 else printf("%d ",w[i]);
41 }
42
43 return 0;
44 }
题目链接:D、Ehab's Last Corollary 参考链接:https://www.cnblogs.com/Last--Whisper/p/13143897.html#
题意:
给出一张 nn 个点的无向连通图和一个常数 kk。你需要解决以下任何一个问题中的一个:
- 找出一个大小为⌈k/2⌉的独立集。
- 找出一个大小不超过k的环。
一条边的长度算作1
独立集: 独立集是一个点的集合,满足其中任意两点之间在原图上没有边直接相连。
题解:
这道题也是肯定是有解的,如果它没有环,那么k/2个点的独立集肯定能找到
如果有环,环的长度小于k直接输出,如果大于k,因为它是最小的环,那么任意一个点只会与环中两个点相连才一起构成一个环。那么这个环绝对能找出来k/2个点独立集
我们可以先假设这个图没有环,那只需要随便找一个点开始染色。然后给与这个点相连的其他点染成另外一种颜色。这样不停的染色直到这个图的每一个点都被染色就可以了
如果后面我们确定了就是没有环,那就输出相同颜色的点就可以了
对于确定是否含有环,我们可以事先定义一个vector容器p用它来装已经dfs遍历过的点,并且如果一个点在这个p容器中那就把这个点在数组is_circle中标记一下。如果一个图里面包含环的话,如下图
我们从1点开始进行dfs,我们可以看到1,2,3,5构成了一个环。我们进行模拟dfs,从1我们会dfs到2,然后从2我们dfs到5,从5我们dfs到3,从3我们dfs到1我们发现1这个点已经被标记过了。那就证明存在环
如果我们发现了环我们不管这个环是不是最小环(例如,如果多一条边2——3,那么1,2,3,5里面就包含一个小环1,2,3),直接让我们遇到那个标记过的点1到我们dfs到现在遇到的所有点都装入一个容器(也就是把1,2,5,3装入另一个容器)
我们这里说一下height数组,这个数组表示的是某一个点是第几深度遍历到的,对于序列1,2,5,3。height[1]=0,height[2]=1,height[5]=2,height[3]=3;
然后枚举每一条边,如果某条边的两个节点x和y的深度不一样且这两个点都在环中,那就证明这个环不是最小环(假设2——3这条边存在),那么x和y就是2和3,那就从这个1,2,3,5的开头和结尾删除节点,直到遇见x或者y就截至
代码:
1 #include<stdio.h>
2 #include<algorithm>
3 #include<iostream>
4 #include<string>
5 #include<queue>
6 #include<deque>
7 #include<string.h>
8 #include<map>
9 #include <iostream>
10 #include <math.h>
11 using namespace std;
12 typedef long long ll;
13 const int maxn=2e5+10;
14 struct shudui
15 {
16 int x,y;
17 } edge[maxn];
18 int n,m,k,height[maxn],is_circle[maxn];
19 vector<int> w[maxn],p,colour[2];
20 deque<int> circle;
21 void dfs(int x,int fa)
22 {
23 height[x]=p.size();
24 p.push_back(x);
25 colour[p.size()%2].push_back(x);
26 for(int i=0; i<w[x].size(); ++i)
27 {
28 int to=w[x][i];
29 if(to==fa) continue;
30 if(height[to]==-1)
31 {
32 dfs(to,x);
33 }
34 else
35 {
36 if(circle.empty())
37 {
38 for(int i=height[to]; i<=height[x]; ++i)
39 {
40 circle.push_back(p[i]);
41 is_circle[p[i]]=1;
42 }
43 }
44 }
45 }
46 p.pop_back();
47 }
48 int main()
49 {
50 memset(height,-1,sizeof(height));
51 scanf("%d%d%d",&n,&m,&k);
52 for(int i=0; i<m; ++i)
53 {
54 int x,y;
55 scanf("%d%d",&x,&y);
56 edge[i].x=x;
57 edge[i].y=y;
58 w[x].push_back(y);
59 w[y].push_back(x);
60 }
61 dfs(1,0);
62 if(circle.empty())
63 {
64 printf("1\n");
65 if(colour[0].size()<colour[1].size()) swap(colour[0],colour[1]);
66 for(int i=0; i<(k+1)/2; ++i)
67 {
68 if(i==0) printf("%d",colour[0][i]);
69 else printf(" %d",colour[0][i]);
70 }
71 printf("\n");
72 return 0;
73 }
74
75 for(int i=0; i<m; ++i)
76 {
77 int x=edge[i].x;
78 int y=edge[i].y;
79 if(is_circle[x] && is_circle[y] && abs(height[x]-height[y])>1)
80 {
81 while (circle.front() != x && circle.front() != y)
82 {
83 is_circle[circle.front()] = false;
84 circle.pop_front();
85 }
86 while (circle.back() != x && circle.back() != y)
87 {
88 is_circle[circle.back()] = false;
89 circle.pop_back();
90 }
91 }
92 }
93
94 if(circle.size()<=k)
95 {
96 printf("2\n%d\n",circle.size());
97 for(int i=0;i<circle.size();++i)
98 {
99 if(i==0) printf("%d",circle[i]);
100 else printf(" %d",circle[i]);
101 }
102 printf("\n");
103 }
104 else
105 {
106 printf("1\n");
107 int sum=0;
108 for(int i=0;i<circle.size();i+=2)
109 {
110 if(i==0) printf("%d",circle[i]);
111 else printf(" %d",circle[i]);
112 sum++;
113 if(sum>=(k+1)/2) break;
114 }
115 printf("\n");
116 }
117 return 0;
118 }
Codeforces Round #649 (Div. 2) C、Ehab and Prefix MEXs D、Ehab's Last Corollary 找环和点染色的更多相关文章
- Codeforces Round #649 (Div. 2)
Codeforces Round #649 (Div. 2) -- WKL \(\mathcal{A}\)题: \(\mathrm{XXXXX}\) Greedy implementation *12 ...
- Codeforces Round #649 (Div. 2) C. Ehab and Prefix MEXs
题目链接:https://codeforces.com/contest/1364/problem/C 题意 给出大小为 $n$ 的非递减数组 $a$,构造同样大小的数组 $b$,使得对于每个 $i$, ...
- Codeforces Round #649 (Div. 2) C. Ehab and Prefix MEXs (构造,贪心)
题意:有长度为\(n\)的数组\(a\),要求构造一个相同长度的数组\(b\),使得\({b_{1},b_{2},....b_{i}}\)集合中没有出现过的最小的数是\(a_{i}\). 题解:完全可 ...
- Codeforces Round #649 (Div. 2) B. Most socially-distanced subsequence
题目链接:https://codeforces.com/contest/1364/problem/B 题意 给出大小为 $n$ 的一个排列 $p$,找出子序列 $s$,使得 $|s_1-s_2|+|s ...
- Codeforces Round #649 (Div. 2) A. XXXXX
题目链接:https://codeforces.com/contest/1364/problem/A 题意 找出大小为 $n$ 的数组 $a$ 的最长连续子数组,其元素和不被 $x$ 整除. 题解 如 ...
- Codeforces Round #649 (Div. 2) E. X-OR 交互 二进制 随机 期望
LINK:X-OR 本来是应该昨天晚上发的 可是昨天晚上 做这道题 写了一个分治做法 一直wa 然后查错 查不出来 心态崩了 想写对拍 发现交互库自己写不出来. 一系列sb操作 == 我都醉了. 今天 ...
- Codeforces Round #649 (Div. 2) B. Most socially-distanced subsequence (数学,差分)
题意:有一长度为\(n\)的数组,求一子序列,要求子序列中两两差的绝对值最大,并且子序列尽可能短. 题解:将数组看成坐标轴上的点,其实就是求每个单调区间的端点,用差分数组来判断单调性. 代码: #in ...
- Codeforces Round #649 (Div. 2) A. XXXXX (贪心)
题意:有一个长度为\(n\)的数组,找一段最长子数组,使得其元素和为\(x\),如果存在,输出子数组的长度,否则输出\(-1\). 题解:这题我们要从元素和\(sum\)来考虑,首先,如果原数组的所有 ...
- Codeforces Round #525 (Div. 2)
Codeforces Round #525 (Div. 2) 哎,忍不住想吐槽一下,又要准备训练,又要做些无聊的事,弄得我都想退出了. 好好的训练不好么???? 只能做出两道水题,其实C题,感觉做出来 ...
随机推荐
- leetcode-222完全二叉树的节点个数
题目 给出一个完全二叉树,求出该树的节点个数. 说明: 完全二叉树的定义如下:在完全二叉树中,除了最底层节点可能没填满外,其余每层节点数都达到最大值,并且最下面一层的节点都集中在该层最左边的若干位置. ...
- ctfshow—web—web2
打开靶机,根据提示是SQL注入 打开后看到登录窗口 方法一.手工注入 抓取数据包 开始SQL注入测试 利用万能密码,登录成功 查看回显位置 查询数据库 查询数据库内数据表 如果想整齐一点显示可以添加g ...
- linux系统中set、env、export关系
set 用来显示shell变量(包括环境变量.用户变量和函数名及其定义),同时可以设置shell选项来开启调试.变量扩展.路径扩展等开关env 用来显示和设置环境变量export 用来显示和设置导出到 ...
- Databricks 第7篇:管理Secret
有时,访问数据要求您通过JDBC对外部数据源进行身份验证,可以使用Azure Databricks Secret来存储凭据,并在notebook和job中引用它们,而不是直接在notebook中输入凭 ...
- Dubbo的设计理念原来就藏在这三张图中
Dubbo在众多的微服务框架中脱颖而出,占据RPC服务框架的半壁江山,非常具有普适性,熟练掌握 Dubbo的应用技巧后深刻理解其内部实现原理,让大家能更好的掌控工作,助力职场,特别能让大家在面试中脱颖 ...
- Docker相关简介以及使用方法
Docker: 可以把它看作是一个软件,在这个软件当中呢,还可以安装其他的软件,还可以把软件所需要的环境依赖一起添加进来,这样让开发人员的程序在不同的环境当中都可以流转起来,避免了程序出现" ...
- JavaScript中创建对象的三种方式!
JavaScript中创建对象的三种方式! 第一种 利用对象字面量! // 创建对象的三种方式! // 1 对象字面量. var obj = { // 对象的属性和方法! name: 'lvhang' ...
- 什么是STP
简介 了解STP 配置STP 相关信息 简介 STP(Spanning Tree Protocol)是运行在交换机上的二层破环协议,环路会导致广播风暴.MAC地址表震荡等后果,STP的主要目的就是确保 ...
- Lambda架构正是这样一种用来处理不能够直接实时计算问题的通用架构
https://mp.weixin.qq.com/s/BGHOw12iCASJy1pgkYZi3w 当数据处理做不到实时,应该怎么办?
- git database 数据库 平面文件 Git 同其他系统的重要区别 Git 只关心文件数据的整体是否发生变化,而大多数其他系统则只关心文件内容的具体差异 Git 的设计哲学
小结: 1.如果要浏览项目的历史更新摘要,Git 不用跑到外面的服务器上去取数据回来 2.注意 git clone 应指定版本,它复制的这个版本的全部历史信息: 各个分支 git init 数据库 ...