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
",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 
",a[n]);
44         }
45         for(int i=1;i<n;i++)
46             printf("%d ",a[i]);
47         printf("%d 
",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 */
Code

然后$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
",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 
",a[n]);
46         }
47         for(int i=1;i<n;i++)
48             printf("%d ",a[i]);
49         printf("%d 
",a[n]);
50     }
51     return 0;
52 }
53 /*
54 1
55 4
56 4 2 1 3
57 */
Code

这是我做过的最自闭的一场Div.3

原文地址:https://www.cnblogs.com/lyttt/p/11797169.html