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
     
  • 相关阅读:
    【Css】SCSS基本语法
    【Css】Scss 与 Sass 简单示例
    【移动端】cordova在app中打开外部链接——cordova-plugin-inappbrowser
    border-radius圆角边框属性讲解
    css 设置 transform 无效
    linux下设置php执行命令
    linux下php命令无法使用如何解决
    微信小程序 --- 表单输入验证(手机号、邮箱验证、输入非空)
    微信小程序倒计时组件开发
    小程序--三级联动
  • 原文地址:https://www.cnblogs.com/crackpotisback/p/4437277.html
Copyright © 2011-2022 走看看