zoukankan      html  css  js  c++  java
  • codeforces 489A.SwapSort 解题报告

    题目链接:http://codeforces.com/problemset/problem/489/A

    题目意思:给出一个 n 个无序的序列,问能通过两两交换,需要多少次使得整个序列最终呈现非递减形式。这个交换次数最多为 n 次。如果原来已经非递减排列好,输出次数为0;否则不但要输出次数,还需要输出每次交换的数组下标。

      比赛的时候想复杂了,用了pair来记录值和坐标,还要开多一个pair类型的 b 数组来保存已排好序的序列,然后跟原序列比较......哪个复杂啊~~~然后校园网12:00 断网了,比原来提早半小时 = =,不过都好,原来的做法是错的。

        其实之所以没有向简单的方法想,是因为被最多 n 次这个条件吓到了,没有仔细想清楚,以为两两比较最终会超 n 次。其实是不会的。

      遍历 0 ~ n-1 的位置,选出最小,然后次小,第三小,.....,直到最大。如果发现当前位置放置的数是正确的,就continue,最多最多交换次数是 O(n) !

        15ms 版本

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 3000 + 10;
     9 int a[maxn];
    10 int res[maxn][2];
    11 
    12 int main()
    13 {
    14     #ifndef ONLINE_JUDGE
    15         freopen("in.txt", "r", stdin);
    16     #endif
    17     int n;
    18 
    19     while (scanf("%d", &n) != EOF)
    20     {
    21         for (int i = 0; i < n; i++)
    22             scanf("%d", &a[i]);
    23         int cnt = 0;
    24         for (int i = 0; i < n; i++)
    25         {
    26             int minn = a[i];
    27             int choice = i;
    28             for (int j = i+1; j < n; j++)
    29             {
    30                 if (a[j] < minn)
    31                 {
    32                     minn = a[j];
    33                     choice = j;
    34                 }
    35             }
    36             if (choice == i)
    37                 continue;
    38             res[cnt][0] = i;
    39             res[cnt++][1] = choice;
    40             swap(a[i], a[choice]);
    41         }
    42         printf("%d
    ", cnt);
    43         for (int i = 0; i < cnt; i++)
    44             printf("%d %d
    ", res[i][0], res[i][1]);
    45     }
    46     return 0;
    47 }

       至于下面这个呢,是参考乌冬子写的,用到 STL 中的 min_element(first, end, cmp),其中cmp为可选择参数!

    表示在[first, end) (看清楚,这个是左闭右开区间)中查找最小的元素。max_element则是查找最大元素。

      这个函数我也是第一次见,*min_element(first, end, cmp)代表这个最小的元素的值。

       假设数组用a[]来表示。min_element(a[i], a[i]+n) - a  才返回最小元素的值的下标!!!

      乌冬子的做法还有一个巧妙的地方,就是即使元素放置位置正确,也原地输出交换下标,即类似输出 i i 这种。而且还有一点就是不需要开多一个数组来存储答案。真应该给个大大的赞他呀~~~~^_^,有一个稍稍瑕疵就是时间用多了,需要 31ms !STL 普遍都是这样的。

      31ms 偷师版   

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <cstdlib>
     4 #include <cstring>
     5 #include <algorithm>
     6 using namespace std;
     7 
     8 const int maxn = 3000 + 10;
     9 int a[maxn];
    10 
    11 int main()
    12 {
    13     #ifndef ONLINE_JUDGE
    14         freopen("in.txt", "r", stdin);
    15     #endif
    16     int n;
    17 
    18     while (scanf("%d", &n) != EOF)
    19     {
    20         for (int i = 0; i < n; i++)
    21             scanf("%d", &a[i]);
    22         printf("%d
    ", n);
    23         for (int i = 0; i < n; i++)
    24         {
    25             int j = min_element(a+i, a+n) - a;
    26             printf("%d %d
    ", i, j);
    27             swap(a[i], a[j]);
    28         }
    29     }
    30     return 0;
    31 }
  • 相关阅读:
    牛客练习赛64 D-宝石装箱(容斥定律,背包)
    CF-GYM-[2019 USP Try-outs] 部分题解
    [Codeforces Round #642 (Div. 3)] ABCDEF题解
    [NCD 2019] G. Ali and the Breakfast (解析几何)
    [AtCoder Beginner Contest 165] E
    [Educational Codeforces Round 86 (Rated for Div. 2)] E. Placing Rooks (组合数学,容斥定律)
    [AtCoder Beginner Contest 164] -E
    牛客算法周周练3 C -小雨坐地铁(分层最短路)
    HDU 5726 GCD (RMQ + 二分)
    Codeforces Round #362 (Div. 2) C. Lorenzo Von Matterhorn (类似LCA)
  • 原文地址:https://www.cnblogs.com/windysai/p/4104937.html
Copyright © 2011-2022 走看看