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)就不会爆了。
代码
#include <bits/stdc++.h> using namespace std; const int max_n = ; int n, m, k;
int x, s;
int a[max_n], b[max_n], c[max_n], d[max_n]; inline int max_complete(int mana_left)
{
int l = , r = k;
while (l < r)
{
int m = (l + r + ) / ;
if (d[m] <= mana_left) l = m; else r = m-;
}
return c[l];
} int main()
{
cin >> n >> m >> k;
cin >> x >> s;
a[] = x;
b[] = ;
c[] = ;
d[] = ;
for (int i = ; i <= m; i++) cin >> a[i];
for (int i = ; i <= m; i++) cin >> b[i];
for (int i = ; i <= k; i++) cin >> c[i];
for (int i = ; i <= k; i++) cin >> d[i];
long long ans = 1LL * n * x;
for (int i = ; i <= m; i++)
{
int mana_left= s - b[i];
if (mana_left< ) continue;
ans = min(ans, 1LL * (n - max_complete(mana_left)) * a[i]);
}
cout << ans << endl;
return ;
}
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个黑棋能否将军。
代码
#include <bits/stdc++.h> using namespace std; const int max_n = ; typedef struct {
char type;
int x;
int y;
}piece; int n, X, Y;
piece a[max_n], near[];
int main()
{
cin >> n;
cin >> X >> Y; // white king
for(int i=; i<n; i++) {
cin >> a[i].type >> a[i].x >> a[i].y;
}
for(int i=; i<n; i++) {
if(a[i].x == X) {
if(a[i].y > Y) {
if(near[].type== || a[i].y-Y < near[].y-Y) {
near[] = a[i];
}
} else {
if(near[].type== || a[i].y-Y > near[].y-Y) {
near[] = a[i];
}
}
} else if(a[i].y == Y) {
if(a[i].x > X) {
if(near[].type== || a[i].x-X < near[].x-X) {
near[] = a[i];
}
} else {
if(near[].type== || a[i].x-X > near[].x-X) {
near[] = a[i];
}
}
} else if(a[i].y == a[i].x + Y - X) {
if(a[i].x > X) {
if(near[].type== || a[i].x-X < near[].x-X) {
near[] = a[i];
}
} else {
if(near[].type== || a[i].x-X > near[].x-X) {
near[] = a[i];
}
}
} else if(a[i].y == - * a[i].x + Y + X){
if(a[i].x > X) {
if(near[].type== || a[i].x-X < near[].x-X) {
near[] = a[i];
}
} else {
if(near[].type== || a[i].x-X > near[].x-X) {
near[] = a[i];
}
}
}
}
for(int i=; i<=; i+=) {
if(near[i].type==) continue;
if(near[i].type == 'Q' || near[i].type == 'R') {
cout << "YES";
return ;
}
}
for(int i=; i<=; i+=) {
if(near[i].type==) continue;
if(near[i].type == 'Q' || near[i].type == 'B') {
cout << "YES";
return ;
}
}
cout << "NO";
return ;
}
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,这个距离就是最长路径长度,使用这种方法只需要遍历图两次。
代码
#include <bits/stdc++.h> using namespace std; int n, cn, diameter=, s;
vector < vector<int> > g;
vector < vector<int> > cg;
vector <int> color;
vector <bool> viewed;
vector <int> comp; void comp_dfs(int v, int col) {
comp[v] = cn;
viewed[v] = true;
int len = g[v].size();
for(int i=; i<len; i++) {
if(viewed[g[v][i]] || color[g[v][i]]!=col) continue;
comp_dfs(g[v][i], col);
}
} void dfs(int v, int d) {
viewed[v] = true;
int len = cg[v].size();
for(int i=; i<len; i++) {
if(viewed[cg[v][i]]) continue;
dfs(cg[v][i],d+);
}
if(d>diameter) {
diameter = d;
s = v;
}
} int main()
{
std::ios::sync_with_stdio(false);
cin >> n;
g.resize(n);
color.resize(n);
for(int i=; i<n; i++) {
cin >> color[i];
}
viewed.resize(n);
viewed.assign(n,false);
for(int i=; i<n-; i++) {
int v1, v2;
cin >> v1 >> v2;
v1--;
v2--;
g[v1].push_back(v2);
g[v2].push_back(v1);
}
comp.resize(n);
cg.resize(n);
// compress
for(int i=; i<n; i++) {
if(!viewed[i]) {
comp_dfs(i,color[i]);
cn++;
}
}
// link
for(int i=; i<n; i++) {
int len = g[i].size();
for(int j=; j<len; j++) {
if(color[i] != color[g[i][j]]) {
cg[comp[i]].push_back(comp[g[i][j]]);
}
}
}
viewed.resize(cn);
viewed.assign(cn,false);
dfs(,);
viewed.assign(cn,false);
dfs(s,);
cout << (diameter)/;
return ;
}
Unfold Code
总结
用vector代替链表来构建邻接表更简单(C++ STL);
comp_dsf只是将最初传入的顶点与其连通的同色点压缩成一个点(赋予相同的压缩后编号),并没有实际建立压缩后的边;
建立边:压缩完所有块后,再遍历原图,颜色不同的相邻点之间必定存在边;
Codeforces Round #379 (Div. 2) 总结分享的更多相关文章
- Codeforces Round #379 (Div. 2) Analyses By Team:Red & Black
A.Anton and Danik Problems: 给你长度为N的,只含'A','D'的序列,统计并输出何者出现的较多,相同为"Friendship" Analysis: lu ...
- Codeforces Round #379 (Div. 2) E. Anton and Tree 缩点 直径
E. Anton and Tree 题目连接: http://codeforces.com/contest/734/problem/E Description Anton is growing a t ...
- Codeforces Round #379 (Div. 2) D. Anton and Chess 水题
D. Anton and Chess 题目连接: http://codeforces.com/contest/734/problem/D Description Anton likes to play ...
- Codeforces Round #379 (Div. 2) C. Anton and Making Potions 枚举+二分
C. Anton and Making Potions 题目连接: http://codeforces.com/contest/734/problem/C Description Anton is p ...
- Codeforces Round #379 (Div. 2) B. Anton and Digits 水题
B. Anton and Digits 题目连接: http://codeforces.com/contest/734/problem/B Description Recently Anton fou ...
- 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) D. Anton and Chess 模拟
题目链接: http://codeforces.com/contest/734/problem/D D. Anton and Chess time limit per test4 secondsmem ...
- 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) D. Anton and Chess —— 基础题
题目链接:http://codeforces.com/contest/734/problem/D D. Anton and Chess time limit per test 4 seconds me ...
随机推荐
- eclipse 配置黑色主题
虽然以前也使用eclipse的黑色主题,但是配置起来稍微麻烦一点. 这里先声明,下面的方式适合最新版本的Eclipse Luna,旧的版本可以下载我提供的这个插件,并将其放在eclipse目录下的pl ...
- C++奇数魔方阵
理解了算法的思想就很简单了, 首先将1放到第一排的中间,然后向左上角走,当行数超过索引,则将该数放到最后一排接下来的一列中去,当列数超过索引,则放到上一排的第一列中去,若都没有超过索引,但是此时的右上 ...
- Linux下一些文件夹的含义
在 Linux系统里面,"分区",被称作"挂载点",简单明了的说,"挂载点"意思就是:把一部分硬盘容量,"分"成一个文件 ...
- iOS多线程编程指南(二)线程管理
当应用程序生成一个新的线程的时候,该线程变成应用程序进程空间内的一个实体.每个线程都拥有它自己的执行堆栈,由内核调度独立的运行时间片.一个线程可以和其他线程或其他进程通信,执行I/O操作,甚至执行任何 ...
- jquery基本选择器,一张页面全搞定
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- TreeView树形控件递归绑定数据库里的数据
TreeView树形控件递归绑定数据库里的数据. 第一种:性能不好 第一步:数据库中查出来的表,字段名分别为UNAME(显示名称),DID(关联数据),UTYPE(类型) 第二步:前台代码 <% ...
- wsdl地址如何在远程服务器上查看源码?
工作需要,接了几个webservice接口,但是厂家给的规范十分不规范,服务名称没一个写对的,要是我的本地电脑可以打开wsdl地址,那倒没什么,察看一下wsdl就可以. 但是好多wsdl地址我本地电脑 ...
- 搭建struts2框架
struts是一个经典的MVC模式拦截器比过滤器拦截的力度更大 搭建struts2框架1.引入lib包 9个(2.3版本的)common-fileupload;common-io;common-lan ...
- 传递引用类型参数(ref)
引用类型的变量不直接包含其数据:它包含的是对其数据的引用. 当通过值传递引用类型的参数时,有可能更改引用所指向的数据,如某类成员的值. 但是无法更改引用本身的值:也就是说,不能使用相同的引用为新类分配 ...
- 利用dbms_metadata.get_ddl查看DDL语句
http://www.cnblogs.com/aocle/archive/2011/10/13/2209790.html 当我们想要查看某个表或者是表空间的DDL的时候,可以利用dbms_metada ...