CF-Div.3-B. Minimize the Permutation【模拟·需要清醒的脑子】
根据字典序,是个人都会想到依次把目前最小的数尽量往前面移动,直到它不能再往前移动,或者已经到了它的期望位置(就是排列的那个位置 比如$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 */
然后$WA$了,一直调调调...自闭ing
后来打了一个对拍,可惜拍出来数据很大,就把错了的地方调出来,然后离散化长这个样子:
1
4
4 2 1 3
啊,我错了,应该是要现在这个数小于前面那个数才能交换,而不是搞什么期望位置啊,因为前面有可能有一些比较小的数不能够到达他的期望位置,然后就被无辜得换到后面去了。
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 //----- 33 if(t>a[pos[t]-1]) 34 { 35 t++; 36 continue; 37 } 38 //----- 39 vis[pos[t]-1]=1; 40 int tmp=a[pos[t]-1]; 41 a[pos[t]-1]=a[pos[t]],a[pos[t]]=tmp; 42 pos[tmp]++,pos[t]--; 43 //for(int i=1;i<n;i++) 44 // printf("%d ",a[i]); 45 //printf("%d \n",a[n]); 46 } 47 for(int i=1;i<n;i++) 48 printf("%d ",a[i]); 49 printf("%d \n",a[n]); 50 } 51 return 0; 52 } 53 /* 54 1 55 4 56 4 2 1 3 57 */
这是我做过的最自闭的一场Div.3
转载请注明出处,有疑问欢迎探讨
博主邮箱 2775182058@qq.com