zoukankan      html  css  js  c++  java
  • ZJU 2425 Inversion

    Inversion

    Time Limit: 2000ms
    Memory Limit: 65536KB
    This problem will be judged on ZJU. Original ID: 2425
    64-bit integer IO format: %lld      Java class name: Main

    The inversion number of an integer sequence a1, a2, ... , an is the number of pairs (ai, aj) that satisfy i < j and ai > aj. Given n and the inversion number m, your task is to find the smallest permutation of the set { 1, 2, ... , n }, whose inversion number is exactly m.

    A permutation a1, a2, ... , an is smaller than b1, b2, ... , bn if and only if there exists an integer k such that aj = bj for 1 <= j < k but ak < bk.


    Input

    The input consists of several test cases. Each line of the input contains two integers n and m. Both of the integers at the last line of the input is -1, which should not be processed. You may assume that 1 <= n <= 50000 and 0 <= m <= 1/2*n*(n-1).


    Output

    For each test case, print a line containing the smallest permutation as described above, separates the numbers by single spaces. Don't output any trailing spaces at the end of each line, or you may get an 'Presentation Error'!


    Sample Input

    5 9
    7 3
    -1 -1


    Sample Output

    4 5 3 2 1
    1 2 3 4 7 6 5

     

    Source

     
    解题:贪心法可解。。。
     
    逆序最大的时候就是反序 $frac{n*(n-1)}{2}$
     那么我们尝试尽可能的反序后面的,因为前面的是高位,反序高位的不能保证字典序最小。
     
    先求出确定后面的多少位是受影响的,先打印前面不受影响的。
     
    后面的第一个就是看前面最后一个数是多少+后面的需要逆序多少+1就是后面受影响的第一个,并且能够保证这个位的数字最小。
     
    前面已经处理到 $n - p$ 了,那么受影响的第一个数位的数字应该就是 $n - p + 1$,由于后面还要逆序,所以应该是  $n - p + 1 + (m - frac{(p-2)*(p-1)}{2})$
     
     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 int n,m;
     4 vector<int>ans;
     5 int main(){
     6     while(scanf("%d %d",&n,&m),~n||~m){
     7         ans.clear();
     8         int p = 1;
     9         for(; p*(p - 1) < (m<<1); p++);
    10         for(int i = 1; i <= n - p; ++i) ans.push_back(i);
    11         int tmp = n - p + (m - ((p-1)*(p-2)>>1)) + 1;
    12         ans.push_back(tmp);
    13         for(int i = n; i > n - p; --i)
    14             if(i != tmp) ans.push_back(i);
    15         for(int i = 0; i < ans.size(); ++i)
    16             printf("%d%c",ans[i],i + 1 == ans.size()?'
    ':' ');
    17     }
    18     return 0;
    19 }
    View Code
     
  • 相关阅读:
    spsss基本统计分析操作攻略
    MATLAB读取Excel表格数据和处理数据
    MATLAB 雷达图画图函数
    spss新手教程
    MATLAB绘制饼状图
    高斯消元法解线性方程组(C++实现)
    Java和matlab混合编程
    Matlab与Java混合编程的教程
    两组数据的相关性分析
    vs2013+QT5环境
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4437277.html
Copyright © 2011-2022 走看看