zoukankan      html  css  js  c++  java
  • 洛谷

    https://www.luogu.org/problemnew/show/P1338
    先打表看了一下规律,居然看出来n的位置是阶梯往前的.而每个阶梯的头头,必有后半段降序.
    再仔细看一下居然每次交换后半段的没被交换过的元素和前半段的最后一个元素.
    打了一个表,不清楚复杂度就交了,当时以为是n²的,因为逆序数最多有 (C_n^2) 但最后事实证明不是.

    因为一开始找阶梯是n的,找到之后这个阶梯的长度最多也是n的,其实复杂度是两个n.

    附带打表代码以及表:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    int main(){
        int n;
        while(cin>>n){
            vector<int> v;
            for(int i=1;i<=n;i++)
                v.push_back(i);
            int maxcnt=-1;
            do{
                int cnt=0;
                for(int i=0;i<n;i++){
                    for(int j=i+1;j<n;j++){
                        if(v[i]>v[j]){
                            cnt++;
                        }
                    }
                }
                if(cnt>maxcnt){
                    for(int i=0;i<n;i++)
                        printf("%d ",v[i]);
                    printf(" cnt=%d
    ",cnt);
                    maxcnt=cnt;
                }
            }while(next_permutation(v.begin(),v.end()));
        }
    }
    
    5
    1 2 3 4 5  cnt=0
    1 2 3 5 4  cnt=1
    1 2 4 5 3  cnt=2
    1 2 5 4 3  cnt=3
    1 3 5 4 2  cnt=4
    1 4 5 3 2  cnt=5
    1 5 4 3 2  cnt=6
    2 5 4 3 1  cnt=7
    3 5 4 2 1  cnt=8
    4 5 3 2 1  cnt=9
    5 4 3 2 1  cnt=10
    
    6
    1 2 3 4 5 6  cnt=0
    1 2 3 4 6 5  cnt=1
    1 2 3 5 6 4  cnt=2
    1 2 3 6 5 4  cnt=3
    1 2 4 6 5 3  cnt=4
    1 2 5 6 4 3  cnt=5
    1 2 6 5 4 3  cnt=6
    1 3 6 5 4 2  cnt=7
    1 4 6 5 3 2  cnt=8
    1 5 6 4 3 2  cnt=9
    1 6 5 4 3 2  cnt=10
    2 6 5 4 3 1  cnt=11
    3 6 5 4 2 1  cnt=12
    4 6 5 3 2 1  cnt=13
    5 6 4 3 2 1  cnt=14
    6 5 4 3 2 1  cnt=15
    
    

    然后是构造表的代码:

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    
    int ans[50005];
    int pos[50005];
    
    int main(){
        ll n,m;
        while(cin>>n>>m){
            //for(int cm=0;cm<=n*(n-1)/2;cm++){
                //ll m=cm;
                for(int i=1;i<=n;i++){
                    ans[i]=i;
                    pos[i]=i;
                }
    
                /*if(m==0){
                    for(int i=1;i<=n;i++)
                        printf("%d%c",ans[i]," 
    "[i==n]);
                    continue;
                }*/
    
                ll sum=0;
                int p=0;
                while(sum<=m){
                    p++;
                    sum+=p;
                }
    
                sum-=p;
                p--;
    
                for(int i=0;i<=p;i++){
                    ans[n-i]=(n-(p-i));
                    pos[n-(p-i)]=i;
                }
    
                /*for(int i=1;i<=n;i++)
                    printf("%d ",ans[i]);
                printf("
    ");*/
    
                int curchange=n;
                while(m>sum){
                    swap(ans[n-p-1],ans[curchange]);
                    m--;
                    curchange--;
                }
    
                for(int i=1;i<=n;i++)
                    printf("%d ",ans[i]);
                printf("
    ");
    
                //cout<<sum<<endl;
            //}
        }
    }
    
  • 相关阅读:
    node.js入门
    分布式爬虫
    ES6入门
    Vue.js入门
    用scrapy爬取亚马逊网站项目
    垃圾回收器
    HTTP协议详解
    有效的邮箱地址
    C#中正则表达式的使用
    抽象类
  • 原文地址:https://www.cnblogs.com/Yinku/p/10691968.html
Copyright © 2011-2022 走看看