• [JZOJ5772]【NOIP2008模拟】今天你AK了吗?


    Description

    AK:All kill
    “你为什么没背书?”
    “没有为什么,我就是没背书。”
    “……我去年买了个表,G—U—N!”
    头铁王InFleaKing把背书的时间都拿去列排列了......
    n=3的排列一共有六个(顺序按字典序从小到大):
    1 2 3
    1 3 2
    2 1 3
    2 3 1
    3 1 2
    3 2 1
    气不打一处来的InFleaKing把n的排列打乱了。
    他想知道字典序第k小的n的排列是什么?
    由于InFleaKing被捉去背书了,所以这个问题只能交给被万人顶礼膜拜的dalao您来解决了。
     

    Input

    一行,两个数,分别是n,k。
    n,k的含义见题目描述。

    Output

    一行,n个数。
    代表字典序第k小的n的排列。
    注意两两数之间要用空格隔开。
     

    Sample Input

    Sample Input1:
    1 1
    
    Sample Input2:
    2 2
     

    Sample Output

    Sample Output1:
    1
    
    Sample Output2:
    2 1
     
     

    Data Constraint

    【数据约定】
    对于10%的数据:1<=n<=3
    对于20%的数据,1<=n<=9
    对于30%的数据:1<=n<=18,1<=k<=10^6
    对于60%的数据:1<=n<=18
    对于80%的数据:1<=n<=100,1<=k<=10^100
    对于90%的数据:1<=n<=1000,1<=k<=10^1000
    对于100%的数据:1<=n<=100000,1<=k<=min(10^20000,n!)

    直接模拟...不知道为什么讲的这么玄学。

    其实是显然的事。

    对于从左到右的位置i,前面有(n-1)!种可能...

    于是就把剩下的数字中第k / (n - 1)!个数选到当前位置, 然后k %= (n - 1)!,

    然后对于后面也是这样。。。

    要写高精不开心,直接弃疗,手懒,我是不会写高精的233.

    复杂度是O(N^2)的过不去,听讲解的什么奇怪算法不太明白为什么要这么做。

    直接用树状数组维护, 再套二分找第k个数就ok了。

    复杂度O(Nlog^2N)。

    考场上O(N^2)能过不写高精的数据,于是弃疗了没写树状数组套二分。

    放上考场60分代码


    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <string>
    #include <queue>
    #include <vector>
    #include <algorithm>
    using namespace std;
    inline int read() {
        int res=0;char c=getchar();bool f=0;
        while(!isdigit(c)) {if(c=='-')f=1;c=getchar();}
        while(isdigit(c))res=(res<<3)+(res<<1)+(c^48),c=getchar();
        return f?-res:res;
    }
    #define ll long long 
    int n;
    unsigned ll k;
    int wei[200005];
    unsigned ll fac[1000005];
    bool vis[1000005];
    
    int main()
    {
        freopen("array.in", "r", stdin);
        freopen("array.out", "w", stdout);
        n = read();
        fac[1] = 1;
        for (int i = 2 ; i <= n ; i ++) fac[i] = fac[i-1] * i;
        cin >> k;
        k--;
        for (register int i = 1 ; i < n ; i ++) 
        {
            int re,sum = 0;
            for (register int j = 1 ; j <= n; j ++) 
            {
                if (sum == k / fac[n-i] + 1) break;
                if (!vis[j]) re = j, sum++;
            }
            printf("%d ", re);
            vis[re] = 1;
            k %= fac[n-i];
        }
        for (register int i = 1 ; i <= n ; i ++) if (!vis[i]) return printf("%d", i), 0;
        return 0;
    }
  • 相关阅读:
    游戏引擎/GUI的设计与实现-主题
    Perl 写的巡检数据库的脚本
    Perl 利用grep 判断元素是否在数组里
    抓报错对应的SQL
    org.hibernate.exception.GenericJDBCException: Could not open connection
    java.sql.SQLException: Access denied for user 'sa'@'localhost' (using password: YES)
    java.sql.SQLException: Access denied for user 'sa'@'localhost' (using password: NO)
    Caused by: java.lang.NoSuchMethodError: javax.persistence.Table.indexes()[Ljavax/persistence/Index
    Caused by: org.h2.jdbc.JdbcSQLException: Table "T_STUDENT_INFO" not found; SQL statement
    No bean named 'hibernateTemplate' is defined
  • 原文地址:https://www.cnblogs.com/BriMon/p/9443353.html
Copyright © 2020-2023  润新知