[解题报告]Codeforces 105D Entertaining Geodetics
Abstract
Codeforces 105D
并查集(官方标的)
Body
Source
http://codeforces.com/problemset/problem/105/D
Description
题意很复杂,自己看……我一开始也没看懂,把那个gif动态图看个10遍以上就懂了。
http://212.193.37.254/codeforces/images/geo_slow.gif
Solution
比较裸的并查集。注意到染色操作实际上就是将原本颜色不同的格子合并到一起即可。计算螺旋形距离的话,实际上只跟格子相对中心格的坐标有关。我是直接找公式,CF上面的代码好像大部分是直接记录,各种step++什么的,看不懂。
但是仔细分析后我觉得,其实和并查集没有什么关系……令当前需要染色的格子集合为S。可以证明,实际上每次染色只会把别的格子并入S,而不会从S中删除或换掉格子(尽管S的颜色不断改变)。于是只用记录S的颜色和大小即可。
P.S. 写得这么简陋还叫解题报告实在是太不好意思了,以后标签改成[代码]好了。
Code
并查集(我写的并查集很长很难看,大家还是看CF上面的代码好了)
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <vector>#include <queue>#include <map>using namespace std; const int S = 303*303*2; typedef long long LL;typedef pair<int, int> pr;pr (*mkpr)(int, int)=make_pair; int N, M;LL ans = 0;map<int, int> color;int f[S], r[S], c[S], s[S];int pan[303][303], sym[303][303];int colorcnt = 0;vector<pr> node[S];queue<pr> q;pr now;int cnow, cchg; inline int getcolor(int x){if (!color.count(x)) color[x] = colorcnt++;return color[x];} inline int dis(int i, int j){int n;if (j <= 0) n = max(abs(j), abs(i)-1);else n = max(abs(j), abs(i))-1;if (i==n+1) return 4*(n+1)*(n+1)+(n+1)-j;else if (j==n+1) return (4*n+2)*(n+1)+(n+1)+i;else if (i==-n-1) return (2*n+1)*(2*n+1)+n+j;else return 4*n*n+2*n+n-i;} bool cmp(const pr &u, const pr &v){return dis(u.first-now.first, u.second-now.second)<dis(v.first-now.first, v.second-now.second);} int find(int x){if (f[x]==x) return x;return f[x] = find(f[x]);} int join(int u, int v){int ru = find(u), rv = find(v);if (ru == rv) return ru;if (r[ru]<r[rv]) { s[rv] += s[ru]; s[ru] = 0;return f[ru] = rv; }else if (r[rv]<r[ru]) { s[ru] += s[rv]; s[rv] = 0;return f[rv] = ru; }else { r[rv]++; s[rv] += s[ru]; s[ru] = 0;return f[ru] = rv; }} void init(){for (int i = 0; i < colorcnt; ++i) { f[i] = i; c[i] = i; r[i] = 0; }} int main(){int i, j, k, x, y, root; scanf("%d%d", &N, &M); color[0] = colorcnt++;for (i = 0; i < N; ++i)for (j = 0; j < M; ++j) { scanf("%d", &pan[i][j]); pan[i][j] = getcolor(pan[i][j]); s[pan[i][j]]++; }for (i = 0; i < N; ++i)for (j = 0; j < M; ++j) { scanf("%d", &sym[i][j]);if (sym[i][j]!=-1) sym[i][j] = getcolor(sym[i][j]); } init(); scanf("%d%d", &x, &y); x--; y--;for (i = 0; i < N; ++i)for (j = 0; j < M; ++j)if (i==x&&j==y) q.push(mkpr(i, j));else if (sym[i][j]!=-1) node[pan[i][j]].push_back(mkpr(i, j));while (!q.empty()) { now = q.front(); q.pop(); i = now.first, j = now.second; root = find(pan[i][j]); cnow = c[root]; cchg = sym[i][j];if (cnow==0 || cnow==cchg) continue; ans += s[root]; vector<pr> elm = node[cnow]; node[cnow].clear(); sort(elm.begin(), elm.end(), cmp);for (k = 0; k < elm.size(); ++k) q.push(elm[k]); f[cchg] = cchg; c[join(root, cchg)] = cchg; } cout << ans << endl;}
非并查集
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>#include <queue>#include <vector>#include <queue>#include <map>using namespace std; const int S = 303*303*2; typedef long long LL;typedef pair<int, int> pr;pr (*mkpr)(int, int)=make_pair; int N, M;LL ans = 0;map<int, int> color;int s[S];int pan[303][303], sym[303][303];int colorcnt = 0;vector<pr> node[S];queue<pr> q;pr now;int snow, cnow, cchg; inline int getcolor(int x){if (!color.count(x)) color[x] = colorcnt++;return color[x];} inline int dis(int i, int j){int n;if (j <= 0) n = max(abs(j), abs(i)-1);else n = max(abs(j), abs(i))-1;if (i==n+1) return 4*(n+1)*(n+1)+(n+1)-j;else if (j==n+1) return (4*n+2)*(n+1)+(n+1)+i;else if (i==-n-1) return (2*n+1)*(2*n+1)+n+j;else return 4*n*n+2*n+n-i;} bool cmp(const pr &u, const pr &v){return dis(u.first-now.first, u.second-now.second)<dis(v.first-now.first, v.second-now.second);} int main(){int i, j, k, x, y; scanf("%d%d", &N, &M); color[0] = colorcnt++;for (i = 0; i < N; ++i)for (j = 0; j < M; ++j) { scanf("%d", &pan[i][j]); pan[i][j] = getcolor(pan[i][j]); s[pan[i][j]]++; }for (i = 0; i < N; ++i)for (j = 0; j < M; ++j) { scanf("%d", &sym[i][j]);if (sym[i][j]!=-1) sym[i][j] = getcolor(sym[i][j]); } scanf("%d%d", &x, &y); x--; y--;for (i = 0; i < N; ++i)for (j = 0; j < M; ++j)if (i==x&&j==y) q.push(mkpr(i, j));else if (sym[i][j]!=-1) node[pan[i][j]].push_back(mkpr(i, j)); cnow = pan[x][y]; snow = 0;while (!q.empty()) { now = q.front(); q.pop(); i = now.first, j = now.second; cchg = sym[i][j];if (cnow==0 || cnow==cchg) continue; snow += s[cnow]; s[cnow] = 0; ans += snow; vector<pr> elm = node[cnow]; node[cnow].clear(); sort(elm.begin(), elm.end(), cmp);for (k = 0; k < elm.size(); ++k) q.push(elm[k]); cnow = cchg; } cout << ans << endl;}
转载于:https://www.cnblogs.com/jffifa/archive/2012/03/21/2410295.html
[解题报告]Codeforces 105D Entertaining Geodetics相关推荐
- 解题报告(十八)数论题目泛做(Codeforces 难度:2000 ~ 3000 + )
整理的算法模板合集: ACM模板 点我看算法全家桶系列!!! 实际上是一个全新的精炼模板整合计划 繁凡出品的全新系列:解题报告系列 -- 超高质量算法题单,配套我写的超高质量的题解和代码,题目难度不一 ...
- Codeforces Round #700 (Div. 2)A~D2解题报告
Codeforces Round #700 (Div. 2)A~D2解题报告 A Yet Another String Game 原题链接 http://codeforces.com/contest/ ...
- Codeforces Round #693 (Div. 3)A~G解题报告
Codeforces Round #693 (Div. 3)A~G解题报告 A Cards for Friends 原题信息 http://codeforces.com/contest/1472/pr ...
- Codeforces Round #697 (Div. 3)A~G解题报告
Codeforces Round #697 (Div. 3)A~G解题报告 题 A Odd Divisor 题目介绍 解题思路 乍一想本题,感觉有点迷迷糊糊,但是证难则反,直接考虑没有奇数因子的情况, ...
- Codeforces Round #698 (Div. 2) A-E解题报告与解法证明
Codeforces Round #698 (Div. 2) A-E解题报告与解法证明 题目解法总体概括 A Nezzar and Colorful Balls #include <bits/s ...
- Codeforces round 654 赛后解题报告
Codeforces round 654 赛后解题报告 先吐槽一下怎么 A-D 都是结论题啊啊 A. Magical Sticks 我们可以先确定下来,我们一定只对于未进行过拼接的木棍拼接. 学过等差 ...
- Codeforces Round #677 (Div. 3)——ABCDE解题报告
Codeforces Round #677 (Div. 3)--ABCDE解题报告 比赛链接:https://codeforces.com/contest/1433 A.Boring Apartmen ...
- codeforces 50A-C语言解题报告
50A题目网址 解题报告-others 题目解析 1.输入n x m大小的木板,使用21大小的多米诺去填满,求最多的多米诺数目 2.通过分析把木板分为奇数和偶数的情况 1)有一边是偶数的情况: 使用2 ...
- Codeforces 438D 线段树 解题报告
D. The Child and Sequence At the children's day, the child came to Picks's house, and messed his hou ...
最新文章
- 有了实例化需求,交付高质量软件不再是空谈
- 网站建设案例欣赏_网站制作设计案例_成都辰星建站
- 文件映射操作类的实现
- 机器人学习--Turtelbot3学习--如何使用cartographer建图
- java web如何配置ask_Javaweb新手之路之JavaWeb开发环境配置篇
- mysql工具的使用_产品操作MySQL入门篇-工具使用
- 选项卡,下拉菜单操做时的页面数据更新,highcharts,d3 结合。
- python开发中遇到的难题_初学者在Python开发中常见的问题(上)
- 拜登将主持商讨网络安全问题,苹果和微软CEO参加
- php脚本搭vps,#分享#基于宝塔面板的ZFaka(发卡程序)一键脚本
- GNOME下也是Alt+F2,输入gnome-terminal
- java 标题栏_如何更改java应用程序标题栏默认图标
- 格拉布斯法—异常值判断(异常值)
- php eclipse 版本_PHPEclipse官方下载
- 8家供应商、2300个特效镜头,ftrack助力《侍神令》协同制作
- 37个自学网站,一年让你省下十几万
- 《研究生科研能力训练与培养》
- 360全景拍摄中相机的白平衡设置
- 微服务之间调用的安全认证-jwt
- 国内主要的PDM产品关于浏览圈阅模块的总结(2006)
热门文章
- 理解 Redux 的最好方式,是自己写一个
- React 高级应用 -- 错误边界 Error Boundaries
- 乱码385b1b926a38153d38957556c0dc55b5
- cygwin 解决 乱码问题 (转)
- Linux下bash:command not found提示
- JS---Math.Random()*10--[0,10)随机变颜色
- hibernate4.3 无法获取数据库最新值
- openstack network
- unity, destroy gameObject destroy all children
- linux笔记:linux帮助命令,man,help,whatis,apropos