• 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

  • 相关阅读:
    NYOJ 734
    NYOJ 762
    NYOJ 743
    NYOJ 478
    NYOJ 451
    NYOJ 461
    NYOJ 485
    NYOJ 333
    平均互信息
    ASCII码
  • 原文地址:https://www.cnblogs.com/lyttt/p/11797169.html
Copyright © 2020-2023  润新知