我是把它当做一道数学题来做的。

这篇题解写的有点啰嗦,但是是我最原始的思维过程。

对于一个集合An= { 1, 2, …, n },在n比较小的情况下,在纸上按字典顺序把所有子集排列一下。

以n=3,m=10举例:


n=3的情况

容易看出前5个打头的是1,紧接着5个子集打头的是2,最后5个开头的是3。

拿前五个来说,除了第一个,后面四个不看开头的1,后面的排列形式和n=2的子集的排列很相似。

f(n)代表集合An所有子集的个数,那么有递推关系:

f(n) = n * (f(n - 1) + 1), f(1) = 1

这里数组taken的作用就是标记某个数是否被占用。

在这个例子里面,要求第一个数,计算(10 - 1) / 5 + 1 = 2。

表示这个数是所有未被占用的数里面从小到大第2个数,也就是2。

再计算一下余数r = (10 - 1) % 5等于4

如果r == 0说明后面的数没有了,跳出循环。

否则m = r;

继续下一轮循环

这里m == 4,计算第二个数 (4 - 1) / 2 + 1 == 2。

现在2已经被第一个数占用了,所以未被占用的第二个数就是3。

后面依次类推。

 //#define LOCAL
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std; int main(void)
{
#ifdef LOCAL
freopen("2062in.txt", "r", stdin);
#endif int n;
bool taken[];
int b[];
long long m, a[];
a[] = ;
for(int i = ; i <= ; ++i)
a[i] = i * (a[i - ] + ); while(scanf("%d%I64d", &n, &m) == )
{
memset(taken, false, sizeof(taken));
int i;
long long r = ;
for(i = ; i <= n; ++i)
{
b[i] = ((m - ) / (a[n - i] + )) + ;
int j, k = ;
for(j = ; j <= n; ++j)
{
if(!taken[j])
++k;
if(k == b[i])
break;
}
b[i] = j;
taken[j] = true;
r = (m - ) % (a[n - i] + );
if(r == )
break;
m = r;
}
for(int j = ; j < i; ++j)
printf("%d ", b[j]);
printf("%d\n", b[i]);
}
return ;
}

代码君

HDU 2062 Subset sequence的更多相关文章

  1. HDU 2062 Subset sequence 数位dp,思路 难度:1

    http://acm.hdu.edu.cn/showproblem.php?pid=2062 Subset sequence Time Limit: 1000/1000 MS (Java/Others ...

  2. HDU 2062 Subset sequence (找规律)

    题目链接 Problem Description Consider the aggregate An= { 1, 2, -, n }. For example, A1={1}, A3={1,2,3}. ...

  3. 题解报告:hdu 2062 Subset sequence

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2062 Problem Description 考虑集合An = {1,2,...,n}. 例如,A1 ...

  4. hdu(2062)-Subset sequence 组合数学

    意甲冠军:查找集合{1,2,3...n}第一m一个排列子. 收集的线索所行的大小. 例两个元素的排列子集合按字典树排列是:{1},{1,2},{2},{2,1}: 解法:一个一个元素来确定,每次把剩余 ...

  5. 【HDOJ】2062 Subset sequence

    这道题目非常好,饶了点儿圈子.我的思路是,先按照组排列.例如,1            2           31 2         2 1        3 11 2 3      2 1 3  ...

  6. HDU 2062:Subset sequence(思维)

    Subset sequence Time Limit: 1000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Tot ...

  7. HDU 5860 Death Sequence(死亡序列)

    p.MsoNormal { margin: 0pt; margin-bottom: .0001pt; text-align: justify; font-family: Calibri; font-s ...

  8. HDU 1711 Number Sequence(数列)

    HDU 1711 Number Sequence(数列) Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...

  9. HDU 1005 Number Sequence(数列)

    HDU 1005 Number Sequence(数列) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Jav ...

随机推荐

  1. 由浅入深了解Thrift之客户端连接池化续

    前文<由浅入深了解Thrift之客户端连接池化>中我们已经实现了服务调用端 连接的池化,实现的过于简陋,离实际的项目运用还很遥远.本文将在进一步改造,主要是两方面:1.服务端如何注册多个服 ...

  2. Javascript 正则表达式_5

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <m ...

  3. java集合之ArrayList的实现原理

    1. ArrayList概述: ArrayList是List接口的可变数组的实现.实现了所有可选列表操作,并允许包括 null 在内的所有元素.除了实现 List 接口外,此类还提供一些方法来操作内部 ...

  4. 怎样强制QQ聊天

    首先复制下面这段网址: http://wp.qq.com/open_webaio.html?sigt=2d3bb7d31517da8c94a1061c6b63dd3203eb633805dcd09ec ...

  5. (转)OpenCV 2.4.8 +VS2010的开发环境配置

    转自:  http://blog.csdn.net/poem_qianmo/article/details/19809337 自己可能需要再进行修改 本系列文章由zhmxy555(毛星云)编写,转载请 ...

  6. SIOCADDRT: No such process

    配置Ubuntu靶机遇到的问题 如果你添加/修改默认网关时遇到这个问题. 原因:你要添加的网关不在你主机所在的网段. 解决方法: 比如你要添加的网关是10.57.50.1 sudo route add ...

  7. java理论基础学习二

    JAVA开发工具 文本编辑器 UltraEdit EditPlus notepad++ 集成开发环境 IDE Integrated Development Enviroment JBuilder  h ...

  8. converntion

    One convention that we have is to use the names of fruits and vegetables for variables(only in small ...

  9. lintcode:交错正负数

    交错正负数 给出一个含有正整数和负整数的数组,重新排列成一个正负数交错的数组. 注意事项 不需要保持正整数或者负整数原来的顺序. 样例 给出数组[-1, -2, -3, 4, 5, 6],重新排序之后 ...

  10. 【PSR规范专题(3)】PSR-2 代码风格规范

    [PSR规范专题(3)]PSR-2 代码风格规范 标签(空格分隔): PHP 转载自:https://github.com/PizzaLiu/PHP-FIG/blob/master/PSR-2-cod ...