zoukankan      html  css  js  c++  java
  • CodeForces Good Bye 2014 B. New Year Permutation

    可能是因为这次没有分Div.1和Div.2,所以感觉题的难度比较大。

    题意:

    给出一个1~n的排列和一个邻接矩阵A,Aij = 1表示可以交换排列的第i项和第j项,问经过若干次交换后,求能够得到最小字典序的排列。

    分析:

    如果a和b可交换,b和c可交换,则a和c也可以交换位置。如果把这n个位置看做顶点,两个可交换的位置连一条边,则图中在同一连通分量的顶点都是可以交换元素的。所以用并查集做就很方便了。

    要想得到字典序最小的排列,直接贪心就可以了。从第一个数开始,首先试试1能不能交换到第一个位置去,否则尝试2,一直到能交换或者没有比开头的数更小的数位置。然后继续尝试第二个数。代码中有个used标记数组,标记这个数是否在前面用过。

     1 #include <cstdio>
     2 #include <algorithm>
     3 
     4 const int maxn = 300 + 5;
     5 char G[maxn][maxn];
     6 int p[maxn], a[maxn], pos[maxn];//pos记录每个数的位置
     7 bool used[maxn];//标记每个数是否用过
     8 
     9 int GetParent(int x)
    10 {
    11     return (p[x] == x ? x : p[x] = GetParent(p[x]));
    12 }
    13 
    14 void Union(int x, int y)
    15 {
    16     int px = GetParent(x), py = GetParent(y);
    17     if(px != py)
    18         p[px] = py;
    19 }
    20 
    21 int main()
    22 {
    23     //freopen("in.txt", "r", stdin);
    24     int n;
    25     scanf("%d", &n);
    26     for(int i = 1; i <= n; ++i) p[i] = i;
    27     for(int i = 1; i <= n; ++i) scanf("%d", &a[i]);
    28     for(int i = 1; i <= n; ++i) scanf("%s", G[i] + 1);
    29 
    30     for(int i = 1; i <= n; ++i) pos[a[i]] = i;
    31 
    32     for(int i = 1; i <= n; ++i)
    33         for(int j = 1; j <= n; ++j)
    34             if(G[i][j] == '1') Union(i, j);
    35 
    36     for(int i = 1; i < n; ++i)
    37     {
    38         used[a[i]] = true;
    39         for(int j = 1; j < a[i]; ++j)
    40         {
    41             if(used[j]) continue;
    42             if(GetParent(i) == GetParent(pos[j]))
    43             {
    44                 used[a[i]] = false;
    45                 used[j] = true;
    46                 int q = pos[j];
    47                 std::swap(a[i], a[q]);  //交换两元素
    48                 std::swap(pos[a[i]], pos[a[q]]);    //同时交换每个数的位置
    49                 break;
    50             }
    51         }
    52     }
    53 
    54     for(int i = 1; i < n; ++i) printf("%d ", a[i]);
    55     printf("%d
    ", a[n]);
    56 
    57     return 0;
    58 }
    代码君
  • 相关阅读:
    hibernate中的缓存和快照
    hibernate中的主键生成策略
    static静态代码块的使用(单例)
    spring aop简单实现
    spring 中常用注解
    spring 配置文件中<property> 的作用
    spring配置文件中引入其他配置文件的方法
    3-29 from xx import xx
    3-28 遇到的问题及解决方法
    3-27 思考以及self本质
  • 原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4198796.html
Copyright © 2011-2022 走看看