lightoj 1060 - nth Permutation(组合数+贪心)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1060

题解:如果是不重复数的这些操作可以用康托展开的逆来求,如果是有重复数字出现康托展开的逆就要稍微变一下。要除去自身个数的组合数具体看一代码,暴力就行

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
typedef long long ll;
ll f[30];
char s[30];
int num[30];
void init() {
    f[1] = f[0] = 1;
    for(int i = 2 ; i <= 20 ; i++) f[i] = f[i - 1] * i;
}
int main() {
    int t , Case = 0;
    scanf("%d" , &t);
    init();
    while(t--) {
        int n;
        scanf("%s %d" , s , &n);
        memset(num , 0 , sizeof(num));
        int len = strlen(s);
        for(int i = 0 ; i < len ; i++) {
            num[s[i] - ‘a‘]++;
        }
        ll Max = f[len];
        for(int i = 0 ; i < 26 ; i++) if(num[i]) Max /= f[num[i]];//最多的组合种类
        printf("Case %d: " , ++Case);
        if(Max < n) { printf("Impossible\n"); continue; }
        for(int i = 0 ; i < len ; i++) {
            for(int j = 0 ; j < 26 ; j++) {
                if(!num[j]) continue;
                ll gg = f[len - i - 1];
                num[j]--;
                for(int l = 0 ; l < 26 ; l++) if(num[l]) gg /= f[num[l]];
                if(gg >= n) {
                    putchar(j + ‘a‘);
                    break;
                }//如果取当第j个字母为当前位的组合数大于n那么肯定符合。有种贪心的思想。
                n -= gg;//否则就是下一个字母这里之所以要减去是因为要求递增下去前面的组合都不行到下一组合肯定要减去上一个组合数。
                num[j]++;
            }
            if(i == len - 1) printf("\n");
        }
    }
    return 0;
}
时间: 2024-11-10 14:40:45

lightoj 1060 - nth Permutation(组合数+贪心)的相关文章

LightOJ - 1067 - Combinations(组合数)

链接: https://vjudge.net/problem/LightOJ-1067 题意: Given n different objects, you want to take k of them. How many ways to can do it? For example, say there are 4 items; you want to take 2 of them. So, you can do it 6 ways. Take 1, 2 Take 1, 3 Take 1, 4

LightOJ - 1005 - Rooks(组合数)

链接: https://vjudge.net/problem/LightOJ-1005 题意: A rook is a piece used in the game of chess which is played on a board of square grids. A rook can only move vertically or horizontally from its current position and two rooks attack each other if one i

LightOJ - 1318 - Strange Game(组合数)

链接: https://vjudge.net/problem/LightOJ-1318 题意: In a country named "Ajob Desh", people play a game called "Ajob Game" (or strange game). This game is actually a game of words. The rules for the game are as follows: It's an N player gam

LightOJ1060 nth Permutation(不重复全排列+逆康托展开)

一年多前遇到差不多的题目http://acm.fafu.edu.cn/problem.php?id=1427. 一开始我还用搜索..后来那时意外找到一个不重复全排列的计算公式:M!/(N1!*N2!*...*Nn!), 然后就靠自己YY出解法,搞了好几天,最后向学长要了数据,然后迷迷糊糊调了,终于AC了. 后来才知道当时想的解法类似于逆康托展开,只是逆康托展开是对于没有重复元素全排列而言,不过有没有重复元素都一个样. 而现在做这题很顺,因为思路很清晰了,另外这做法和数论DP的统计部分有相似之处.

Codeforces Round #436 (Div. 2)【A、B、C、D、E】

Codeforces Round #436 (Div. 2) 敲出一身冷汗...感觉自己宛如智障:( codeforces 864 A. Fair Game[水] 题意:已知n为偶数,有n张卡片,每张卡片上都写有一个数,两个人每人选一个数,每人可以拿的卡片必须写有是自己选的数,问能否选择两个数使得两个人每人拿的卡片数一样多并且能拿光卡片.[就是看输入是不是只有两种数字] //:第一遍我看成字符串包含有选的数字也能拿,,这样写着居然过了..水题水题.. 1 #include<cstdio> 2

LightOJ 1166 Old Sorting 置换群 或 贪心 水题

LINK 题意:给出1~n数字的排列,求变为递增有序的最小交换次数 思路:水题.数据给的很小怎么搞都可以.由于坐标和数字都是1~n,所以我使用置换群求循环节个数和长度的方法. /** @Date : 2017-07-20 14:45:30 * @FileName: LightOJ 1166 贪心 或 置换群 水题.cpp * @Platform: Windows * @Author : Lweleth ([email protected]) * @Link : https://github.co

lightoj 1095 - Arrange the Numbers(dp+组合数)

题目链接:http://www.lightoj.com/volume_showproblem.php?problem=1095 题解:其实是一道简单的组合数只要推导一下错排就行了.在这里就推导一下错排 dp[i]=(i-1)*dp[i-2](表示新加的那个数放到i-1中的某一个位置然后那个被放位置的数放在i这个位置就是i-2的错排)+(i-1)*dp[i-1](表示新加的那个数放到i-1中的某一个位置然后用那个位置被占的数代替i这个位置的数就是i-1的错排) #include <iostream

HDU 6044--Limited Permutation(搜索+组合数+逆元)

题目链接 Problem Description As to a permutation p1,p2,?,pn from 1 to n, it is uncomplicated for each 1≤i≤n to calculate (li,ri) meeting the condition that min(pL,pL+1,?,pR)=pi if and only if li≤L≤i≤R≤ri for each 1≤L≤R≤n. Given the positive integers n, (

LightOJ - 1246 Colorful Board(DP+组合数)

http://lightoj.com/volume_showproblem.php?problem=1246 题意 有个(M+1)*(N+1)的棋盘,用k种颜色给它涂色,要求曼哈顿距离为奇数的格子之间不能涂相同的颜色,每个格子都必须有颜色,问可行的方案数. 分析 经一波分析,根据曼哈顿距离为奇数这一信息,可以将棋盘分为两部分,也就是相邻格子不能有相同颜色.一种颜色只能在一个部分中出现.现在考虑对一个部分的格子操作, dp[i][j]表示i个格子选择用了j种颜色的方案数,于是可以得到这样的递推式: