codeforces 500B.New Year Permutation 解题报告
题目链接:http://codeforces.com/problemset/problem/500/B
题目意思:给出一个含有 n 个数的排列:p1, p2, ..., pn-1, pn。紧接着是一个 n * n 的矩阵A,当且仅当 Aij = 1 时,pi 与 pj 可以交换数值。现在问如何交换数值,使得最后得到的排列字典序最小。
比赛的时候不会做,看了Tutorial 1 的解法,觉得别人做得太巧妙了,出题者也出得很好 ^_^
可以看这个:http://codeforces.com/blog/entry/15488
它是利用了并查集来做的。如果遇到 Aij = 1 的话,就将点 i 和 点 j 连一条边。最终会得到一些互不相交的集合。以第一组 test 来说吧~~~
这就表示位置 1、4、7 的数是可以交换的,位置 2、5 要保持原封不动,位置 3、6 的数可以交换。由于每个集合都有一个祖先,即第一层的那个数,依次为 7、2、5、6,然后就把每个集合的数放到以该集合祖先为首的 vector 数组里面,并把每个集合内的数从小到大排序。最后遍历位置 1 ~ n,根据每个位置的数所属的集合(以哪个祖先为首),依次输出。
只能说,解题思路真是太巧妙兼神奇!竟然可以转化成图!继续干爸爹吧 ^_^
- #include <iostream>
- #include <cstdio>
- #include <cstring>
- #include <algorithm>
- #include <vector>
- using namespace std;
- const int maxn = + ;
- int p[maxn], cnt[maxn];
- int group[maxn];
- char s[maxn];
- vector<int> vi[maxn];
- int find(int x)
- {
- if (x == group[x])
- return x;
- return group[x] = find(group[x]);
- }
- void merge(int x, int y)
- {
- int fx = find(x);
- int fy = find(y);
- if (fx != fy)
- group[fx] = fy;
- }
- int main()
- {
- #ifndef ONLINE_JUDGE
- freopen("in.txt", "r", stdin);
- #endif // ONLINE_JUDGE
- int n;
- while (scanf("%d", &n) != EOF)
- {
- vi[n].clear();
- for (int i = ; i <= n; i++) {
- scanf("%d", &p[i]);
- group[i] = i;
- }
- for (int i = ; i <= n; i++) {
- scanf("%s", s+);
- for (int j = ; j <= n; j++) {
- if (s[j] == '') {
- merge(i, j);
- }
- }
- }
- for (int i = ; i <= n; i++) {
- vi[find(i)].push_back(p[i]); // 千万不要写成 vi[group[i]].push_back(p[i]);
- }
- for (int i = ; i <= n; i++) {
- sort(vi[i].begin(), vi[i].end());
- }
- memset(cnt, , sizeof(cnt));
- for (int i = ; i <= n; i++) {
- int g = group[i];
- printf("%d%c", vi[g][cnt[g]++], i == n ? '\n' : ' ');
- }
- }
- return ;
- }
注意,代码中的 51 行的部分,如果写成 vi[group[i]].push_back(p[i]) 是错的!以第二个 test 为例,group[1] = 3,find[1] = 5。find[i] 才会找到最终的祖先!!!
codeforces 500B.New Year Permutation 解题报告的更多相关文章
- codeforces B. Levko and Permutation 解题报告
题目链接:http://codeforces.com/problemset/problem/361/B 题目意思:有n个数,这些数的范围是[1,n],并且每个数都是不相同的.你需要构造一个排列,使得这 ...
- Codeforces Educational Round 92 赛后解题报告(A-G)
Codeforces Educational Round 92 赛后解题报告 惨 huayucaiji 惨 A. LCM Problem 赛前:A题嘛,总归简单的咯 赛后:A题这种**题居然想了20m ...
- codeforces 476C.Dreamoon and Sums 解题报告
题目链接:http://codeforces.com/problemset/problem/476/C 题目意思:给出两个数:a 和 b,要求算出 (x/b) / (x%b) == k,其中 k 的取 ...
- Codeforces Round #382 (Div. 2) 解题报告
CF一如既往在深夜举行,我也一如既往在周三上午的C++课上进行了virtual participation.这次div2的题目除了E题都水的一塌糊涂,参赛时的E题最后也没有几个参赛者AC,排名又成为了 ...
- codeforces 483C.Diverse Permutation 解题报告
题目链接:http://codeforces.com/problemset/problem/483/C 题目意思:给出 n 和 k,要求输出一个含有 n 个数的排列 p1, p2, ...,pn,使得 ...
- codeforces B. Permutation 解题报告
题目链接:http://codeforces.com/problemset/problem/359/B 题目意思:给定n和k的值,需要构造一条长度为2n(每个元素取值范围只能是[1,2n])且元素各不 ...
- codeforces 507B. Amr and Pins 解题报告
题目链接:http://codeforces.com/problemset/problem/507/B 题目意思:给出圆的半径,以及圆心坐标和最终圆心要到达的坐标位置.问最少步数是多少.移动见下图.( ...
- codeforces B. Xenia and Ringroad 解题报告
题目链接:http://codeforces.com/problemset/problem/339/B 题目理解不难,这句是解题的关键 In order to complete the i-th ta ...
- codeforces 462C Appleman and Toastman 解题报告
题目链接:http://codeforces.com/problemset/problem/461/A 题目意思:给出一群由 n 个数组成的集合你,依次循环执行两种操作: (1)每次Toastman得 ...
随机推荐
- 网站全面采用UTF-8方法
先是概念的理解: Unicode/UCS的压缩形式--UTF8出现了,套用官方网站的首句话『UTF-8 stands for Unicode Transformation Format-8. It i ...
- I’ve seen the world,lit it up as my stage now
I've seen the world,lit it up as my stage now 阅尽繁华 点亮红尘做舞台 Channeling angels in,the new age now 粉末登场 ...
- OS X Framework Library not loaded: 'Image not found'的解决办法
参考:OS X Framework Library not loaded: 'Image not found' 1.首先将相应的framework手动复制到/System/Library/Framew ...
- 常用开源镜像站整理android sdk manager
http://www.cocoachina.com/programmer/20151023/13852.html http://android-mirror.bugly.qq.com:8080/inc ...
- Redis学习笔记五:独立功能之事务
Redis 事务提供了一种将多个命令请求打包,然后一次性.按顺序地执行多个命令的机制,并且在事务执行期间,服务器不会中断,会将事务中的所以命令都执行完毕才去处理其他客户端的命令请求. 事务的实现 事务 ...
- BZOJ1030——文本生成器
给你若干给字符串,再给你一个m,问长度是m的字符串中包含给定字符串的数量mod 10007是多少 这个拿过来啥思路也没有,后来还是看了题解,才知道,原来,原来....那个带fail的Trie还可以搞别 ...
- 小技巧-a标签去除蓝圈
可以看到,蓝色的边框破坏了页面的整体美感,很多时候我们都是不需要的.通过设置相应的css可以去除点击过后的蓝色边框. map area { outline: none; } 效果如图,点击过后厌人的蓝 ...
- ubuntu安装python一些安装包
sudo apt-get install python-pip sudo pip install distribute sudo pip install nose sudo pip install v ...
- Android学习笔记(十七)——数据库操作(下)
//此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 这一次我们来试一试升级数据库,并进行数据库的CRUD操作,其中, C 代表添加(Create) ,R 代表查询 ...
- vSphere、Hyper-V与XenServer 你选哪个?
vSphere.Hyper-V与XenServer 你选哪个? 当在VMware vSphere.Microsoft Hyper-V与Citrix Systems XenServer之间做出选择时,v ...