• UVa 10570 外星人聚会


    https://vjudge.net/problem/UVA-10570

    题意:
    输入1~n的排列,每次可以交换两个整数,求出最少交换次数使之变成有序的环状序列。

    思路:
    主要的解题方法就是寻找置换环,举个例子来说吧,因为起点可以是任意位置,我们假设起点在1的位置。

    比如说  5 1 3 4 2 7 6 8 ,第一个数5应该在第5个位置,此时第5个位置上为2,而2应该在第2个位置,此时第2个位置上为1,而1应该在第一个位置即5的位置。因此{5,1,2}构成了一个置换群,别的也是这样的分析,总共可以分为{5,1,2},{3},{4},{6,7},{8}5个置换环,所以交换次数为8-5=3。这个也很好理解,如果每个数都在正确的位置上,那么每个数各自构成一个置换环,那么相减之后就是0了。

     1 #include<iostream> 
     2 #include<cstring>
     3 #include<string>
     4 #include<algorithm>
     5 using namespace std;
     6 
     7 int n;
     8 int a[1100],b[1100];
     9 int vis[1100];
    10 
    11 void dfs(int k, int start)
    12 {
    13     if (vis[k])     return;
    14     vis[k] = 1;
    15     int t = a[k + start];
    16     dfs(t, start);
    17 }
    18 
    19 void dfs2(int k, int start)
    20 {
    21     if (vis[k])     return;
    22     vis[k] = 1;
    23     int t = a[start-k];
    24     dfs2(t, start);
    25 }
    26 
    27 int main()
    28 {
    29     //freopen("D:\txt.txt", "r", stdin);
    30     while (cin >> n && n)
    31     {
    32         int num;
    33         for (int i = 0; i < n; i++)
    34         {
    35             cin >> a[i];
    36             a[i + n] = a[i];
    37         }
    38         int count = 0;
    39 
    40         //正序
    41         for (int i = 0; i < n; i++)   //枚举起点
    42         {
    43             memset(vis, 0, sizeof(vis));
    44             num = 0;
    45             for (int j = 0; j < n; j++)
    46             {
    47                 if (!vis[j])
    48                 {
    49                     num++;
    50                     dfs(j, i);
    51                 }
    52             }
    53             count = max(num, count);
    54         }
    55 
    56         //逆序
    57         for (int i = 2 * n - 1; i >= n;i--)   //枚举起点
    58         {
    59             memset(vis, 0, sizeof(vis));
    60             num = 0;
    61             for (int j = 0; j < n; j++)
    62             {
    63                 if (!vis[j])
    64                 {
    65                     num++;
    66                     dfs2(j, i);
    67                 }
    68             }
    69             count = max(num, count);
    70         }
    71         int ans = n - count;
    72         cout << ans << endl;
    73     }
    74 }
  • 相关阅读:
    犯错记录(一)
    BullseyeCoverage:代码覆盖率。
    测试工具:insure++
    C++ 常见容器
    linux修改rm指令执行(数据安全)
    C++细节系列(零):零散记录
    vim中使用gdb。
    vim自动补全文章搜集
    排序算法的个人心得体会。
    面向对象的三个特征。
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/6484347.html
Copyright © 2020-2023  润新知