lightoj 1060 - nth Permutation(组合数+贪心)
2024-09-01 00:50:11
题目链接: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;
}
最新文章
- Jdbc如何从PostgreSql读取海量数据?PostgreSql源代码分析纪录
- 【原】就IOS发布app时如何保护文本资源的一个方法
- 基础知识《六》---Java集合类: Set、List、Map、Queue使用场景梳理
- eclipse右击打war包class没打上去的问题
- OC 类别(分类)Categroy
- HDU 5776 sum (模拟)
- [poj 2186]Popular Cows[Tarjan强连通分量]
- 总结:spring 的ioc 知识点
- java.lang.OutOfMemoryError: PermGen space 解决方案
- DNS服务架设 redhat linux
- Redis 小白指南(二)- 基础命令和五大类型:字符串、散列、列表、集合和有序集合
- Mybatis与JDBC批量插入MySQL数据库性能测试及解决方案
- 北大poj- 1013
- Android 展示控件之Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系
- 设计模式之模板模式 template
- plsql developer 使用sys用户登录,报ORA-01031权限不足,解决sys(dba权限用户)远程登录报错。
- SQL SERVER中LIKE使用变量类型输出结果不同
- 深入理解 Java 内存模型(一)- 内存模型介绍
- k8s集群搭建指南
- Quartz2D-二维画图引擎 、自己定义UI控件