UVa 11925

链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=3076

题意:

对于一个升序的排列1~n(1≤n≤300),用不超过2n^2次操作把它变成给定的排列。
操作只有两种:交换前两个元素(操作1);把第一个元素移动到最后(操作2)。

分析:

可以对给定的排列做个映射,然后将问题转换为:
对于给定的一个1~n(1≤n≤300)的排列,用不超过2n^2次操作把它变成升序。
然后用冒泡排序的思想即可。

代码:

 1 #include <cstdio>
 2 #include <deque>
 3 #include <algorithm>
 4 using namespace std;
 5 
 6 int cor[300+5];
 7 deque<int> Q;
 8 
 9 void shift(){ //操作2
10     Q.push_back(Q.front());
11     Q.pop_front();
12     printf("2");
13 }
14 
15 void change(){ //操作1
16     swap(Q[0], Q[1]);
17     printf("1");
18 }
19 
20 int main(){
21     int n;
22     while(scanf("%d", &n) && n){
23         Q.clear();
24         for(int x, i = 0; i < n; i++){
25             scanf("%d", &x);
26             cor[x] = i + 1;
27             Q.push_back(x);
28         }
29         for(int i = 0; i < n; i++) Q[i] = cor[i+1]; //对给定的排列做映射
30 
31         int cur = n, p = find(Q.begin(), Q.end(), n) - Q.begin(); //cur是当前调整的数字,p指向该位置
32         for(; Q[p] == Q[(n+p-1)%n] + 1; p = (n+p-1)%n) cur--; //若当前数字已经安排到正确的相对位置,则跳过
33         if(cur == n) cur--; //跳过第一个,因为它已经到了正确的相对位置
34 
35         while(cur > 0){
36             while(Q[0] != cur) shift();
37             while(Q[0] > Q[1]){
38                 change();
39                 if(cur > 2) shift();
40             } //将当前调整的数字移到Q[0],并且其后面的数字是Q[0]+1
41             cur--;
42             for(p = 0; Q[p] == Q[(n+p-1)%n] + 1; p = (n+p-1)%n) cur--;
43         }
44         while(Q[0] != 1) shift();
45         printf("
");
46     }
47     return 0;
48 }
原文地址:https://www.cnblogs.com/hkxy125/p/8422637.html