二中模拟赛 9.11

第一题 permutation

是一道爱斯基摩人的逆序对题(形容它不裸的程度)

如果从上往下看,会发现横线的作用是交换当前它左右两侧的数。因此这道题的第一部分可以直接从上往下暴力swap。

对于第二部分,把这样一张图倒过来看,可以发现倒过来的图也就是把一个排列经过m次交换恢复顺序。

而最少的横线数,也就是最少的交换次数,就是逆序对数。

第一部分模拟交换+第二部分归并排序统计逆序对数 100分

#include<cstdio>
using namespace std;
const int N=1000007;
int n,m,hx[N],a[N],c[N],cnt;
void sort(int l,int r)
{
    if(l==r) return;
    int mid=l+r>>1;int t=l,q=mid+1,p=l-1;
    sort(l,mid);sort(mid+1,r);
    while(q<=r&&t<=mid)
    {
        if(a[t]>a[q])
        {
            cnt+=mid-t+1;
            c[++p]=a[q];q++;
        }
        else c[++p]=a[t++];
    }
    while(q<=r) c[++p]=a[q++];
    while(t<=mid)c[++p]=a[t++];
    for(int i=l;i<=r;i++) a[i]=c[i];
}
void swap(int &x,int &y)
{
    int temp=x;x=y;y=temp;
}
int main()
{
    scanf("%d%d",&n,&m);
    for(int i=1;i<=m;i++) scanf("%d",&hx[i]);
    for(int i=1;i<=n;i++) a[i]=i; 
    for(int i=1;i<=m;i++) swap(a[hx[i]],a[hx[i]+1]);
    for(int i=1;i<=n;i++) printf("%d ",a[i]);
    sort(1,n);
//-        for(int i=1;i<=n;i++) printf("%d ",a[i]);
    printf("\n%d",cnt);
}

考试的时候以为是道图论题,在那方面想了半天没想出来就放弃了。还是太年轻。

猜你喜欢

转载自www.cnblogs.com/IvyLH03/p/11517409.html
今日推荐