Codeforces Round #379 (Div. 2) 总结分享
第一次Virtual participation,contest时只ac了A、B两道,感觉这两道题没什么好说的,直接从C题开始。
C. Anton and Making Potions
题意
制作n瓶药水,初始时每制作一瓶花费x秒,有两类法术,第一类(包含m个法术)使制作每瓶药的时间由x变为a[i] (a[i] < x) 并消耗b[i]点法力值,第二种(k个法术)能瞬间制造c[i]瓶并消耗d[i]点法力值,初始法力值为s,最多在两种类型中分别选一个法术来加快进度。求制作这n瓶药水最少花费的时间。
分析
暴力法肯定爆时间O(m*k),所以没敢用。之后看Tutorial,第一类就暴力,第二类在第一类的基础上二分查找,这样O(m*log2k)就不会爆了。
代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int max_n = 1000000; 6 7 int n, m, k; 8 int x, s; 9 int a[max_n], b[max_n], c[max_n], d[max_n]; 10 11 inline int max_complete(int mana_left) 12 { 13 int l = 0, r = k; 14 while (l < r) 15 { 16 int m = (l + r + 1) / 2; 17 if (d[m] <= mana_left) l = m; else r = m-1; 18 } 19 return c[l]; 20 } 21 22 int main() 23 { 24 cin >> n >> m >> k; 25 cin >> x >> s; 26 a[0] = x; 27 b[0] = 0; 28 c[0] = 0; 29 d[0] = 0; 30 for (int i = 1; i <= m; i++) cin >> a[i]; 31 for (int i = 1; i <= m; i++) cin >> b[i]; 32 for (int i = 1; i <= k; i++) cin >> c[i]; 33 for (int i = 1; i <= k; i++) cin >> d[i]; 34 long long ans = 1LL * n * x; 35 for (int i = 0; i <= m; i++) 36 { 37 int mana_left= s - b[i]; 38 if (mana_left< 0) continue; 39 ans = min(ans, 1LL * (n - max_complete(mana_left)) * a[i]); 40 } 41 cout << ans << endl; 42 return 0; 43 }
Unfold Code
总结
虽然最大只有2e5,内存足够的情况下,max_n稍大一点更好;
abcd[0]存放特殊元素,好处是使后续操作统一化,不必写额外语句去判断特殊情况;
数字的LL后缀代表这是一个long long型常量,1LL*int 将int变成long long;
二分法查找近似数(如:找到比给定值小的最大元素),这里的第二类本身是有序的(非递减的),适用二分查找法;
D. Anton and Chess
题意
一个无限大的棋盘,一个白王和n个黑色棋子(车、象、皇三种),判断白王是否被将军了。车走十字,象走对角线,皇既可走十字,又可走对角线。
分析
在王的8个方向中,判断每个方向离王最近的黑棋能否将军即可。知道王的坐标,8个方向可以用函数表示出来,分别为y=y0,x=x0,y=x+y0-x0,y=-x+y0+x0。黑棋坐标代进去就知道是不是在这8个方向上,然后保存各个方向离白王最近的黑棋,再判断这8个黑棋能否将军。
代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int max_n = 1000000; 6 7 typedef struct { 8 char type; 9 int x; 10 int y; 11 }piece; 12 13 int n, X, Y; 14 piece a[max_n], near[9]; 15 int main() 16 { 17 cin >> n; 18 cin >> X >> Y; // white king 19 for(int i=0; i<n; i++) { 20 cin >> a[i].type >> a[i].x >> a[i].y; 21 } 22 for(int i=0; i<n; i++) { 23 if(a[i].x == X) { 24 if(a[i].y > Y) { 25 if(near[3].type==0 || a[i].y-Y < near[3].y-Y) { 26 near[3] = a[i]; 27 } 28 } else { 29 if(near[7].type==0 || a[i].y-Y > near[7].y-Y) { 30 near[7] = a[i]; 31 } 32 } 33 } else if(a[i].y == Y) { 34 if(a[i].x > X) { 35 if(near[1].type==0 || a[i].x-X < near[1].x-X) { 36 near[1] = a[i]; 37 } 38 } else { 39 if(near[5].type==0 || a[i].x-X > near[5].x-X) { 40 near[5] = a[i]; 41 } 42 } 43 } else if(a[i].y == a[i].x + Y - X) { 44 if(a[i].x > X) { 45 if(near[2].type==0 || a[i].x-X < near[2].x-X) { 46 near[2] = a[i]; 47 } 48 } else { 49 if(near[6].type==0 || a[i].x-X > near[6].x-X) { 50 near[6] = a[i]; 51 } 52 } 53 } else if(a[i].y == -1 * a[i].x + Y + X){ 54 if(a[i].x > X) { 55 if(near[8].type==0 || a[i].x-X < near[8].x-X) { 56 near[8] = a[i]; 57 } 58 } else { 59 if(near[4].type==0 || a[i].x-X > near[4].x-X) { 60 near[4] = a[i]; 61 } 62 } 63 } 64 } 65 for(int i=1; i<=8; i+=2) { 66 if(near[i].type==0) continue; 67 if(near[i].type == 'Q' || near[i].type == 'R') { 68 cout << "YES"; 69 return 0; 70 } 71 } 72 for(int i=2; i<=8; i+=2) { 73 if(near[i].type==0) continue; 74 if(near[i].type == 'Q' || near[i].type == 'B') { 75 cout << "YES"; 76 return 0; 77 } 78 } 79 cout << "NO"; 80 return 0; 81 }
Unfold Code
E. Anton and Tree
题意
一个无环无向图(acyclic undirected gragh),有白和黑两种颜色的顶点,一次选择一个顶点,使与其连通的相同颜色的顶点一起变为另一种颜色。欲使所有顶点变成同一种颜色,求最少执行几次操作?
分析
既然同一块连通的颜色一起改变,那就可以把这样的一块压缩成一个点;可以用一个线性表来储存原图顶点与压缩图顶点的对应编号,①.每次选一个点dfs,确定出一个压缩点,也就是说:所有点访问一遍就能确定每个原图顶点与压缩图顶点的对应编号(此时还没形成压缩图的边);②.然后再遍历一次原图,通过比较邻接点的颜色与自身是否相同,来确定哪些压缩点之间是存在边的。 通过这两个操作就能构建一个压缩顶点图,然后再找到这个无环无向图的最长路径/2就是结果(压缩后的图是黑白相间的,随便画一条出来看看就知道了);关键是如何找到这条最长路径,其实很简单,先随便找一个点v,找到离点v距离最远的点s,则s必定是最长路径两端点的其中之一,这里可用反证法证明(设最长路另一端点为t,假设存在一个不是最长路端点s'的点到v的距离大于s,则最长路将会是s'---t,而不是s---t,矛盾);再由s找到距离最远的点t,这个距离就是最长路径长度,使用这种方法只需要遍历图两次。
代码
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int n, cn, diameter=1, s; 6 vector < vector<int> > g; 7 vector < vector<int> > cg; 8 vector <int> color; 9 vector <bool> viewed; 10 vector <int> comp; 11 12 void comp_dfs(int v, int col) { 13 comp[v] = cn; 14 viewed[v] = true; 15 int len = g[v].size(); 16 for(int i=0; i<len; i++) { 17 if(viewed[g[v][i]] || color[g[v][i]]!=col) continue; 18 comp_dfs(g[v][i], col); 19 } 20 } 21 22 void dfs(int v, int d) { 23 viewed[v] = true; 24 int len = cg[v].size(); 25 for(int i=0; i<len; i++) { 26 if(viewed[cg[v][i]]) continue; 27 dfs(cg[v][i],d+1); 28 } 29 if(d>diameter) { 30 diameter = d; 31 s = v; 32 } 33 } 34 35 int main() 36 { 37 std::ios::sync_with_stdio(false); 38 cin >> n; 39 g.resize(n); 40 color.resize(n); 41 for(int i=0; i<n; i++) { 42 cin >> color[i]; 43 } 44 viewed.resize(n); 45 viewed.assign(n,false); 46 for(int i=0; i<n-1; i++) { 47 int v1, v2; 48 cin >> v1 >> v2; 49 v1--; 50 v2--; 51 g[v1].push_back(v2); 52 g[v2].push_back(v1); 53 } 54 comp.resize(n); 55 cg.resize(n); 56 // compress 57 for(int i=0; i<n; i++) { 58 if(!viewed[i]) { 59 comp_dfs(i,color[i]); 60 cn++; 61 } 62 } 63 // link 64 for(int i=0; i<n; i++) { 65 int len = g[i].size(); 66 for(int j=0; j<len; j++) { 67 if(color[i] != color[g[i][j]]) { 68 cg[comp[i]].push_back(comp[g[i][j]]); 69 } 70 } 71 } 72 viewed.resize(cn); 73 viewed.assign(cn,false); 74 dfs(0,1); 75 viewed.assign(cn,false); 76 dfs(s,1); 77 cout << (diameter)/2; 78 return 0; 79 }
Unfold Code
总结
用vector代替链表来构建邻接表更简单(C++ STL);
comp_dsf只是将最初传入的顶点与其连通的同色点压缩成一个点(赋予相同的压缩后编号),并没有实际建立压缩后的边;
建立边:压缩完所有块后,再遍历原图,颜色不同的相邻点之间必定存在边;
转载于:https://www.cnblogs.com/Zhniing/p/cf379d2.html
Codeforces Round #379 (Div. 2) 总结分享相关推荐
- Codeforces Round #379 (Div. 2) A. Anton and Danik 水题
A. Anton and Danik 题目连接: http://codeforces.com/contest/734/problem/A Description Anton likes to play ...
- Codeforces Round #379 (Div. 2) E. Anton and Tree —— 缩点 + 树上最长路
题目链接:http://codeforces.com/contest/734/problem/E E. Anton and Tree time limit per test 3 seconds mem ...
- Codeforces Round #379 (Div. 2) E. Anton and Tree
题意: 给一颗树 每个节点有黑白2色 可以使一个色块同事变色,问最少的变色次数. 思路: 先缩点 把一样颜色的相邻点 缩成一个 然后新的树 刚好每一层是一个颜色. 最后的答案就是树的直径/2 不过我用 ...
- Codeforces Round #506 (Div. 3)
Codeforces Round #506 (Div. 3) 实习期间事不多,对div3 面向题解和数据编程了一波 A. Many Equal Substrings 题目链接 A题就是找后缀和前缀重合 ...
- Codeforces Round #563 (Div. 2)/CF1174
Codeforces Round #563 (Div. 2)/CF1174 CF1174A Ehab Fails to Be Thanos 其实就是要\(\sum\limits_{i=1}^n a_i ...
- 构造 Codeforces Round #302 (Div. 2) B Sea and Islands
题目传送门 1 /* 2 题意:在n^n的海洋里是否有k块陆地 3 构造算法:按奇偶性来判断,k小于等于所有点数的一半,交叉输出L/S 4 输出完k个L后,之后全部输出S:) 5 5 10 的例子可以 ...
- Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解(每日训练 Day.16 )
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #696 (Div. 2) (A ~ E)超高质量题解 比赛链接:h ...
- Codeforces Round #712 Div.2(A ~ F) 超高质量题解(每日训练 Day.15 )
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 Codeforces Round #712 Div.2(A ~ F) 题解 比赛链接:https:// ...
- Codeforces Round #701 (Div. 2) A ~ F ,6题全,超高质量良心题解【每日亿题】2021/2/13
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 目录 A - Add and Divide B - Replace and Keep Sorted C ...
最新文章
- 德国政府发布新网络安全战略
- 为docker设置国内镜像【转】
- 验证用户身份Filter过滤器
- 传智学员信息登记表html代码_IT兄弟连 HTML5教程 HTML5文字版面和编辑标签 使用HTML表格...
- c语言常量结构体的成员,c语言之结构体
- linux之写C代码出现warning: format not a string literal and no format arguments [-Wformat-security]
- C语言二维数组找出交集,【leetcode C语言实现】剑指 Offer 04. 二维数组中的查找...
- python第七章_Python第七章
- BZOJ4653 [NOI2016] 区间 【线段树】
- 【latex论文】IEEE论文模板的使用教程
- 【电磁】Matlab模拟电机内电磁场的分布附GUI界面
- 查看 win 系统开机关机,启动时间
- 平板app尺寸html5,app界面设计尺寸规范大全
- 前端绘制小猪佩奇(CSS)
- 小说里的管理软件现状
- 打工思维VS创业思维,对比哪三个方面不同
- BBR学习笔记--什么是BBR、可调整的参数
- C++实践 走出迷宫
- LAMMPS后处理以及编程技巧
- 数字电子技术基础(八):超前进位加法器
热门文章
- java构造方法可以是私有的吗_Java中的构造函数可以私有吗?
- 多元统计分析朱建平pdf_应用多元统计分析课后答案朱建平版[精心整理].doc
- electron sqlite3_Electron+React+Antd工程搭建
- 后端传输流跨域_Java开发中解决Js的跨域问题过程解析
- java有几大对象_一个 Java 对象到底有多大?
- java 采集上下滚屏_关于java游戏滚屏的问题!(如何实现)!
- Android项目图像资源保存在,将图像从drawable保存到android中的内部文件存储
- java 优先队列_优先队列Java
- VS 工程只生成dll不生成lib的解决方案
- 产品经理面试:为什么想做产品经理