rockethon2015 B题 Permutations 规律+构造

题意:求使所给公式值最大的第m个排列。

思路:假设已知使f(p)最大的n-1的排列,那么对于使f(p)最大的n的排列,把n放在(n-1)两边均可。因为n放在(n-1)两边,增值为

1+2+...+n,而如果不放在两边,(n-1)到n之间的值<n-1,那么增值一定小于(n+1)n/2。接下来枚举1-->n摆放位置,对于i,如果m<2^(n-i-1),

那么i摆在pos,不然放到可放到的最后面,即last位置。因为接下来(i+1)一定在i左边,而之后比(i+1)大也一定在i左边。详见代码:

/*********************************************************
  file name: B.cpp
  author : kereo
  create time:  2015年02月08日 星期日 21时45分31秒
*********************************************************/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
#include<set>
#include<map>
#include<vector>
#include<stack>
#include<cmath>
#include<string>
#include<algorithm>
using namespace std;
typedef long long ll;
const int sigma_size=26;
const int N=50+10;
const int MAXN=100000+50;
const int inf=0x3fffffff;
const double eps=1e-8;
const int mod=1000000000+7;
#define L(x) (x<<1)
#define R(x) (x<<1|1)
#define PII pair<int, int>
#define mk(x,y) make_pair((x),(y))
int n;
ll m;
int ans[N];
ll base[N];
int main(){
    base[0]=1;
    for(int i=1;i<N;i++)
        base[i]=base[i-1]*2;
    while(~scanf("%d%lld",&n,&m)){
        int pos=1,last=n;
        for(int i=1;i<=n;i++){
            ll tmp=base[n-1-i];
            if(m<=tmp)
                ans[pos++]=i;
            else{
                m-=tmp;
                ans[last--]=i;
            }
        }
        for(int i=1;i<=n;i++){
            if(i == 1)
                printf("%d",ans[i]);
            else
                printf(" %d",ans[i]);
        }
        printf("\n");
    }
	return 0;
}
时间: 2024-12-21 21:01:40

rockethon2015 B题 Permutations 规律+构造的相关文章

HDU 1337 The Drunk Jailer--(模拟题找规律)

题意:有n个监狱,共n轮,第 i 轮警察会去编号为 i 的倍数的监狱,如果是锁的就开锁,如果是开的就锁上,求n轮过后有多少犯人会逃出来 分析:这题实际上是个模拟题,因为数据很小我直接用两重循环模拟的,如果数据很大的话,就不能直接模拟了,模拟题卡时间多半是找规律. 这题的规律是:如果一个监狱被查看了偶数次的话相当于则什么都没发生,还是锁的,也就是说找没有锁上的监狱只要n以内找因数为奇数个的数有多少个即可 代码: #include<iostream> using namespace std; in

HDU 5703 Desert 水题 找规律

已知有n个单位的水,问有几种方式把这些水喝完,每天至少喝1个单位的水,而且每天喝的水的单位为整数.看上去挺复杂要跑循环,但其实上,列举几种情况之后就会发现是找规律的题了= =都是2的n-1次方,而且这题输出二进制数就行了......那就更简单了,直接输出1,然后后面跟n-1个0就行了╮(╯_╰)╭ 下面AC代码 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm>

Codeforces 476D Dreamoon and Sets 规律+构造

题目链接:点击打开链接 题意: 输出n组集合,每组4个. 对于任意一组中的4个元素,一组内任意2个数的gcd==k 且n组的所有数字各不相同. 要使得n组中最大的数字最小. 问: 输出最大的那个数,并输出n组的数字. 思路: 首先能得到,当把这组数字都/k,则任意两个数互质. 然后就是规律: 1 2 3 5 7 8 9 11 对应+6 #include <cstdio> #include <iostream> #include <cstring> #include &l

BNU29140——Taiko taiko——————【概率题、规律题】

Taiko taiko Time Limit: 1000ms Memory Limit: 65536KB 64-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next Type: None None   Graph Theory       2-SAT       Articulation/Bridge/Biconnected Component      

hdu 4810 思维题+二进制位规律+异或规律 213南京现场赛题

http://acm.hdu.edu.cn/showproblem.php?pid=4810 以前做过一些涉及异或的题,化为二进制形式,然后统计0,1个数是一种很常见的处理方法,但是在做这个题的时候居然没尝试,脑残啊...... 一开始看5s时限,感觉稍微暴力一点应该可以,于是YY的O(n^3)算法但是没去实现,明显超时啊,大致就是通过C(n,1)的组合可以在O(n^2)内处理出C(n,2)的组合,在通过C(n,2)处理出C(n,3)的组合....但是C(n,2)已经是n^2个数了,所以算法是O

2014-2015 CT S02E10 C题 Coin Graph 构造+贪心

题意:给定一个数s,构造一个无向图,使得任意两点的最短路径和为s. 思路:二分找到n,满足n×(n-1)/2<=s,且n尽可能大.这样的图,相当于n个点每两个点都连一条边.窝们考虑这样一种构造方法, 假设现在有n个点,我们按照逆时针方向(顺时针也行)排序编号,那么我们间隔删去不相邻点的的边,比如5个点,我们删去 1--3,1--4,...,1--n-2,1---n-1,保留2,删3--5,3--6,...3--n-2,3----n-1,保留4,删5--7,5--8,...,5--n-1.这样可以

rockethon2015 G2题 Inversions problem 概率dp

题意:给定n,k.k次操作,每次等概率将一个区间翻转,问最后逆序数对的期望. 思路:设dp[i][j]表示a[i]在a[j]前面的概率.每次枚举翻转的区间,更新dp[i][j],复杂度为O(n^4×k).详见代码: /********************************************************* file name: G.cpp author : kereo create time: 2015年02月09日 星期一 11时32分13秒 ************

UVa 11925 Generating Permutations (构造法)

题意:给定一个序列,让你从一个升序列变成该序列,并且只有两种操作,操作1:交换前两个元素,操作2:把第一个元素移动到最后. 析:一开始的时候吧,不会,还是看的题解,首先是要逆序来做,这样可能好做一点,那么操作1不变,操作2变成把最后一个元素放到最前面. 就像是冒泡排序一样,如果第一个元素大于第二个,交换顺序,否则就把最后一个元素移动到最前面,但第三个样例就死循环了,我也算过,这样会一直重复某几个状态, 所以我们要维护第一个值,如果是最大的元素,那么就不让他们交换了. 代码如下: #include

SGU 238 Uncle Vasya and Bags for Potatoes 规律+构造

题目链接:点击打开链接 题意: 地上有n个背包,编号从1-n 下面n行第i行: 第一个数字表示背包i里有几个背包. 这样就得到了n个背包的一个状态. 问:有多少个背包状态可以通过一系列的操作达到输入的状态. 每步操作: 选取一个在地面上的背包a,然后把a背包内部的背包放到地上,把地上的放到a背包内部 思路: 我们可以把背包的嵌套关系 用一个图来表示. 就得到了一个森林,然后以地面为根把所有在地上的包相连,就得到了一棵树. 那么对于每次操作相当于换根操作. 所以一共有n-1个方法可以把根移动到其他