根据字典序,是个人都会想到依次把目前最小的数尽量往前面移动,直到它不能再往前移动,或者已经到了它的期望位置(就是排列的那个位置 比如$i$就应该在位置$i$)为止。
所以我刚开始是这么写的:
1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #include<vector> 5 using namespace std; 6 #define N 105 7 #define ll long long 8 int n; 9 int a[N],pos[N]; 10 bool vis[N]; 11 int main() 12 { 13 int T;scanf("%d",&T); 14 while(T--) 15 { 16 scanf("%d",&n); 17 for(int i=1;i<=n;i++) 18 { 19 scanf("%d",&a[i]); 20 vis[i]=0,pos[a[i]]=i; 21 } 22 int t=1; 23 while(1) 24 {//第i次 i和i+1交换 25 //printf("**%d %d\n",t,pos[t]); 26 if(t>=n) break; 27 if(vis[pos[t]-1]) 28 {//这一个数不能再往前挪了 29 t++; 30 continue; 31 } 32 if(pos[t]<=t) 33 { 34 t++; 35 continue; 36 } 37 vis[pos[t]-1]=1; 38 int tmp=a[pos[t]-1]; 39 a[pos[t]-1]=a[pos[t]],a[pos[t]]=tmp; 40 pos[tmp]++,pos[t]--; 41 //for(int i=1;i<n;i++) 42 // printf("%d ",a[i]); 43 //printf("%d \n",a[n]); 44 } 45 for(int i=1;i<n;i++) 46 printf("%d ",a[i]); 47 printf("%d \n",a[n]); 48 } 49 return 0; 50 } 51 /* 52 1 53 4 54 4 2 1 3 55 */ 56 /* 57 //----- 58 if(t>a[pos[t]-1]) 59 { 60 t++; 61 continue; 62 } 63 //----- 64 */