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\n", cnt); 43 for (int i = 0; i < cnt; i++) 44 printf("%d %d\n", 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", n); 23 for (int i = 0; i < n; i++) 24 { 25 int j = min_element(a+i, a+n) - a; 26 printf("%d %d\n", i, j); 27 swap(a[i], a[j]); 28 } 29 } 30 return 0; 31 }
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步