复制代码
 1 #include <bits/stdc++.h>
 2 //分块法
 3 using namespace std;
 4 
 5 template <class T>/*模板,表示给一个未排序的数组排序后对应的下标*/
 6 vector<int> make_index(const vector<T>& a, int start_id) {
 7     int n = a.size();
 8     vector<pair<T, int> > t(n);
 9     for (int i = 0; i < n; i++) {
10         t[i] = make_pair(a[i], i);/*先给一个初始下标*/
11     }
12     sort(t.begin(), t.end());/*排序一波*/
13     vector<int> id(n);
14     for (int i = 0; i < n; i++) {
15         id[t[i].second] = start_id + i;/*排序后的真实下标返回*/
16     }
17     return id;
18 }
19 
20 int main() {
21     ios::sync_with_stdio(false); cin.tie(0);
22     int n; cin >> n;
23     vector<int> s(n);
24     queue<int> q;
25     for (int& x : s) cin >> x;/*新方法,引用地遍历,输入就能实际地改变参数,成功输入*/
26     s = make_index(s, 0);/*从下标0开始给id*/
27     /*lambda函数:auto 函数名  = [捕获方式]{lambda表达式}*/
28     /*用途:书写小型函数,快速使用*/
29     auto in = [&] { cout << "+"; q.push(s.back()); s.pop_back(); };
30     auto out = [&] { cout << "-"; s.push_back(q.front()); q.pop(); };
31     while (s.size()) in();/*in表示入队*/
32     int K = ceil(sqrt(n)), not_sorted = n;/*K表示分成的每一段的长度*/
33     while (not_sorted) {
34         int k = min(K, not_sorted);/*取(K和没排过的数目)的最小值,防止越界*/
35         int L = n - not_sorted, R = L + k - 1;
36         for (int i = 0; i < not_sorted; i++) {
37             if (q.front() >= L && q.front() <= R) {//排序后下标在[L,R]这段区间里
38                 out();//出队
39                 in();//入队
40             }
41             else {//不在
42                 out();//出队
43             }
44         }
45         for (int i = R; i >= L; i--) {
46             int sz = q.size();
47             for (int j = 0; j < sz; j++) {
48                 if (q.front() == i) {
49                     out();/*对应的下标符合,出队,入栈*/
50                 }
51                 else {/*否则回到队伍*/
52                     out();
53                     in();
54                 }
55             }
56         }
57         for (int i = 0; i < not_sorted; i++) in();/*没排的再入队*/
58         for (int i = 0; i < k; i++) out();/*排好的出队,放入堆栈*/
59         not_sorted -= k;
60     }
61     cout << "!\n";
62     return 0;
63 }
复制代码

 

复制代码
 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn = 1010;
 4 typedef pair<int, int> pii;
 5 pii arr[maxn];
 6 stack<pii> st;
 7 queue<pii> qu;
 8 
 9 int main() {
10     int n;
11     scanf("%d", &n);
12     for (int i = 1; i <= n; i++) {
13         scanf("%d", &arr[i].first);//值放first
14         arr[i].second = i;//下标放在second
15         st.push(arr[i]);
16     }
17     sort(arr + 1, arr + n + 1);//排序,得到排序后应该的样子
18     int jg = n;
19     for (int i = 1; i <= n; i++) {
20         printf("+");
21         qu.push(st.top());
22         st.pop();
23     }
24     queue<pii> interval;//interval:间隔,区间
25     int maax = 1;
26     /*
27              一个队列加一个栈,实现快速排序
28         方式:手动的 模拟函数栈的堆栈弹栈的过程
29         
30     */
31     interval.push({ 1, n });//(1,n)的堆栈
32     while (maax) {
33         pii tmp;
34         maax = 0;//当长度无法更新为比0更大,即表明排序完成,退出外循环
35         do {
36             tmp = interval.front();//取最上层的堆栈
37             interval.pop();//弹栈
38             int le = tmp.first, ri = tmp.second;//left,right端点
39             int mid = (le + ri) >> 1;//中点
40             maax = max(maax, ri - le);//更新区间最大长度
41             if (le != ri) {//端点不meet
42                 interval.push({ le, mid });//左半边堆栈
43                 interval.push({ mid + 1, ri });//右半边堆栈
44                 pii x = arr[mid];//pivot值
45                 pii y;
46                 int cnt = 0;
47                 for (int i = le; i <= ri; i++) {
48                     y = qu.front();
49                     printf("-");//不管怎么样先push回到stack
50                     if (y > x) {/*比较大的数先呆在stack里*/
51                         qu.pop();
52                         st.push(y);
53                         cnt++;
54                     }
55                     else {/*比较小的数重新push回队列*/
56                         printf("+");
57                         qu.pop();
58                         qu.push(y);
59                     }
60                 }
61                 while (cnt--) {/*stack里刚才放的数取出来push进队列里*/
62                     y = st.top();
63                     st.pop();
64                     qu.push(y);
65                     printf("+");
66                 }
67             }
68             else {//如果左端点右端点meet
69                 interval.push({ le, ri });
70                 qu.push(qu.front());
71                 qu.pop();
72                 printf("-+");//一去一回,回到队列中,完成排序动作
73             }
74         } while (tmp.second != n);//当没有排到第n个数,就继续分治
75     }
76     for (int i = 1; i <= n; i++) {//队列里的数返回stack中即可
77         printf("-");
78         qu.pop();
79     }
80     printf("!");//华丽结束
81     return 0;
82 }
复制代码

 

复制代码
 1 #include <bits/stdc++.h>
 2 /*二进制基数解法*/
 3 using namespace std;
 4 
 5 int main() {
 6     ios::sync_with_stdio(false);
 7     cin.tie(0);
 8     int n;
 9     cin >> n;
10     vector<int> s(n);
11     queue<int> q;
12     for (int& x : s) cin >> x;
13     auto in = [&] {
14         cout << "+";
15         q.push(s.back());
16         s.pop_back();
17     };
18     auto out = [&] {
19         cout << "-";
20         s.push_back(q.front());
21         q.pop();
22     };
23     while (s.size()) in();
24     int mask = 0;
25     for (int j = 19; j >= 0; j--) {
26         mask |= (1 << (j + 1));
27         int y = 0;
28         for (int i = 0; i < n; i++) {
29             int x = q.front();
30             if (i > 0 && (x & mask) != (y & mask)) {
31                 while (s.size()) in();
32             }
33             y = x;
34             out();
35             if (!((x >> j) & 1)) in();
36         }
37         while (s.size()) in();
38     }
39     while (q.size()) out();
40     cout << "!\n";
41     return 0;
42 }
复制代码