UVa Problem Solution: 10152 - ShellSort

本文介绍了一种基于栈结构的龟排序算法,通过寻找逆序龟中编号最大的龟并将其移至顶部来实现排序。该算法确保所有逆序龟最终都会爬出栈外。

Let the required stack to be the sorted sequence, and the original stack to be the sequence to sort. A turtle is numbered by its position in the required stack: the top is 0, the second is 1, and so on. A turtle is said in reverse order if its number is less than the biggest number of the turtles above it in. Each time, find the turtle with the maximum number of all the turtles in reversed order, and let it climb up to the top.

In fact, all the turtles that have ever been in reverse order need to crawl out of the stack. Choose turtle with the maximum number would keep it from crawling out again.

Code:
  1. /*************************************************************************
  2.  * Copyright (C) 2008 by liukaipeng                                      *
  3.  * liukaipeng at gmail dot com                                           *
  4.  *************************************************************************/
  5. /* @JUDGE_ID 00000 10152 C++ "ShellSort" */
  6. #include <algorithm>
  7. #include <cstdio>
  8. #include <cstring>
  9. #include <deque>
  10. #include <fstream>
  11. #include <iostream>
  12. #include <list>
  13. #include <map>
  14. #include <queue>
  15. #include <set>
  16. #include <stack>
  17. #include <string>
  18. #include <vector>
  19. using namespace std;
  20.      
  21. int const namesize = 81;
  22. int const turtlecount = 200;
  23.           
  24. struct strcomp
  25. {
  26.   bool operator()(char const *s1, char const *s2)
  27.   { return strcmp(s1, s2) < 0; }
  28. };
  29. int sort_turtles(int *turtles, int nturtles, int moves[])
  30. {
  31.   int nmoves = 0;
  32.   while (true) {
  33.     int curm = -1;
  34.     int revm = -1;
  35.     int move = -1;
  36.     for (int i = 0; i < nturtles; ++i) {
  37.       if (turtles[i] > curm) {
  38.         curm = turtles[i];
  39.       } else if (turtles[i] < curm && turtles[i] > revm) {
  40.         revm = turtles[i];
  41.         move = i;
  42.       }
  43.     }
  44.     if (revm < 0) break;
  45.     for (int i = move; i > 0; --i) turtles[i] = turtles[i-1];
  46.     turtles[0] = revm;
  47.     moves[nmoves++] = revm;
  48.   }
  49.   return nmoves;
  50. }
  51. int main(int argc, char *argv[])
  52. {
  53. #ifndef ONLINE_JUDGE
  54.   freopen((string(argv[0]) + ".in").c_str(), "r", stdin);
  55.   freopen((string(argv[0]) + ".out").c_str(), "w", stdout);
  56. #endif
  57.   int ncases;
  58.   cin >> ncases;
  59.   while (ncases-- > 0) {
  60.     int nturtles;
  61.     cin >> nturtles;
  62.     cin.ignore(2048, '/n');
  63.     char origin[turtlecount][namesize];
  64.     for (int i = 0; i < nturtles; ++i) {
  65.       cin.getline(origin[i], namesize);
  66.     }
  67.     char names[turtlecount][namesize];
  68.     map<char *, int, strcomp> nameids;
  69.     for (int i = 0; i < nturtles; ++i) {
  70.       cin.getline(names[i], namesize);
  71.       nameids.insert(make_pair(names[i], i));
  72.     }
  73.     int turtles[turtlecount];
  74.     for (int i = 0; i < nturtles; ++i) {
  75.       turtles[i] = nameids[origin[i]];
  76.     }
  77.     int moves[turtlecount];
  78.     int nmoves = sort_turtles(turtles, nturtles, moves);
  79.     for (int i = 0; i < nmoves; ++i) {
  80.       cout << names[moves[i]] << '/n';
  81.     }
  82.     cout << '/n';
  83.   }
  84.   return 0;
  85. }

评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值