题目链接:https://ac.nowcoder.com/acm/contest/70/D

题目大意:

  略

分析:

  注意到12! < 10^9 < 13!,于是当n > 13时,第k号排列的前n - 13位是确定的。比如n = 15吧,那么无论k取何值,第k号排列都是形如:“12xxxxxxxxxxxxx”,后面的x代表其他数字,因为后面13个x,有13!种排列,大于10^9。于是平移一下就退化成n = 13的情况了,同时不要忘了把前n - 13位种满足条件的幸运数算一下。

  对于n <= 13的情况,如果直接从第一个排列生成到第k个排列势必会超时,这里就要用到康托展开求出排列,然后遍历一遍即可。

  关于康托展开是什么,看大佬链接:http://www.cnblogs.com/linyujun/p/5205760.html

代码如下:

 #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std; #define INIT() std::ios::sync_with_stdio(false);std::cin.tie(0);
#define Rep(i,n) for (int i = 0; i < (n); ++i)
#define For(i,s,t) for (int i = (s); i <= (t); ++i)
#define rFor(i,t,s) for (int i = (t); i >= (s); --i)
#define ForLL(i, s, t) for (LL i = LL(s); i <= LL(t); ++i)
#define rForLL(i, t, s) for (LL i = LL(t); i >= LL(s); --i)
#define foreach(i,c) for (__typeof(c.begin()) i = c.begin(); i != c.end(); ++i)
#define rforeach(i,c) for (__typeof(c.rbegin()) i = c.rbegin(); i != c.rend(); ++i) #define pr(x) cout << #x << " = " << x << " "
#define prln(x) cout << #x << " = " << x << endl #define LOWBIT(x) ((x)&(-x)) #define ALL(x) x.begin(),x.end()
#define INS(x) inserter(x,x.begin()) #define ms0(a) memset(a,0,sizeof(a))
#define msI(a) memset(a,inf,sizeof(a))
#define msM(a) memset(a,-1,sizeof(a)) #define pii pair<int,int>
#define piii pair<pair<int,int>,int>
#define MP make_pair
#define PB push_back
#define ft first
#define sd second template<typename T1, typename T2>
istream &operator>>(istream &in, pair<T1, T2> &p) {
in >> p.first >> p.second;
return in;
} template<typename T>
istream &operator>>(istream &in, vector<T> &v) {
for (auto &x: v)
in >> x;
return in;
} template<typename T1, typename T2>
ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {
out << "[" << p.first << ", " << p.second << "]" << "\n";
return out;
} typedef long long LL;
typedef unsigned long long uLL;
typedef pair< double, double > PDD;
typedef set< int > SI;
typedef vector< int > VI;
const double EPS = 1e-;
const int inf = 1e9 + ;
const LL mod = 1e9 + ;
const int maxN = 1e5 + ;
const LL ONE = ; // 12! < 1e9 < 13!
LL n, k, ans;
LL b; // 偏移 LL lucky[], len;
LL fac[] = {, , , , , , , , , , , , , , , , , , , , }; /**
* @brief 康托展开,把数字转换成排列
* @param A 所要求的从1~k的一个排列
* @param num 排列A对应的数字,范围从0~k!-1
* @param k 所要求的的排列长度
*
* @return 无
*/
void cantor(int A[], LL num, int k) {
int t;
bool vis[k];//0到k-1,表示是否出现过
ms0(vis);
Rep(i, k){
t = num / fac[k - i - ];
num = num % fac[k - i - ];
// 找出尚未被标记过的第t大的数
for(int j = , pos = ; ; ++j, ++pos){
if(vis[pos]) --j;
if(j == t){
vis[pos] = true;
A[i] = pos + ; // 排列是从1开始的,所以要记得加1
break;
}
}
}
} /**
* @brief 康托逆展开,把排列转换成数字
* @param A 从1~k的一个排列
* @param num 排列A对应的数字,范围从0~k!-1
* @param k 排列长度
*
* @return 无
*/
void inv_cantor(int A[], LL &num, int k) {
int cnt;
num = ;
Rep(i, k) {
cnt = ;
// 判断A[i]后面有几个数小于它
For(j, i + , k - ) if(A[i] > A[j]) cnt ++;//判断几个数小于它
num += fac[k - i - ] * cnt;
}
} // 求所有幸运数
inline void dfs(LL x, int cnt) {
if(cnt > ) return;
lucky[len++] = x;
dfs(x* + , cnt + );
dfs(x* + , cnt + );
} bool check(LL x) {
int tmp = find(lucky, lucky + len, x) - lucky;
return tmp < len;
} int main(){
INIT();
cin >> n >> k;
dfs(, );
sort(lucky, lucky + len); if(n > ) {
b = n - ;
n = ;
ans = upper_bound(lucky, lucky + len, b) - lucky;
--ans;
}
if(k > fac[n]) {
cout << - << endl;
return ;
} //利用康托展开计算排列序列
int s[];
cantor(s, k - , n); Rep(i, n) if(check(i + b + ) && check(s[i] + b)) ++ans; cout << ans << endl;
return ;
}

牛客练习赛13D 幸运数字4的更多相关文章

  1. 牛客练习赛13B 幸运数字2

    题目链接:https://ac.nowcoder.com/acm/contest/70/B 题目大意: 略 分析: 先DFS求出所有幸运数,然后暴力即可 代码如下: #pragma GCC optim ...

  2. 牛客练习赛13D:幸运数字Ⅳ(康托展开) F:关键字排序

    链接:https://www.nowcoder.com/acm/contest/70/D 题目: 定义一个数字为幸运数字当且仅当它的所有数位都是4或者7. 比如说,47.744.4都是幸运数字而5.1 ...

  3. 牛客练习赛13D

    定义一个数字为幸运数字当且仅当它的所有数位都是4或者7.比如说,47.744.4都是幸运数字而5.17.467都不是.现在想知道在1...n的第k小的排列(permutation,https://en ...

  4. 牛客提高D2t2 幸运数字考试

    分析 预处理出所有合法数字 然后直接lower_bound查询即可 代码 #include<iostream> #include<cstdio> #include<cst ...

  5. 牛客练习赛48 C 小w的糖果 (数学,多项式,差分)

    牛客练习赛48 C 小w的糖果 (数学,多项式) 链接:https://ac.nowcoder.com/acm/contest/923/C来源:牛客网 题目描述 小w和他的两位队友teito.toki ...

  6. 牛客练习赛48 A· 小w的a+b问题 (贪心,构造,二进制)

    牛客练习赛48 A· 小w的a+b问题 链接:https://ac.nowcoder.com/acm/contest/923/A来源:牛客网 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C ...

  7. 牛客练习赛53 D 德育分博弈政治课 (思维建图,最大流)

    牛客练习赛53 D德育分博弈政治课 链接:https://ac.nowcoder.com/acm/contest/1114/D来源:牛客网 题目描述 德育分学长最近玩起了骰子.他玩的骰子不同,他的骰子 ...

  8. 【并查集缩点+tarjan无向图求桥】Where are you @牛客练习赛32 D

    目录 [并查集缩点+tarjan无向图求桥]Where are you @牛客练习赛32 D PROBLEM SOLUTION CODE [并查集缩点+tarjan无向图求桥]Where are yo ...

  9. 牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 逻辑,博弈 B

    牛客练习赛31 B 赞迪卡之声妮莎与奥札奇 https://ac.nowcoder.com/acm/contest/218/B 时间限制:C/C++ 1秒,其他语言2秒 空间限制:C/C++ 2621 ...

随机推荐

  1. Python学习之函数进阶

    函数的命名空间 著名的python之禅 Beautiful is better than ugly. Explicit is better than implicit. Simple is bette ...

  2. CSAPP:第六章 存储器层次结构

    存储器层次结构 关键点:内存 6.1 随机访问存储器6.2 局部性6.3 存储器层次结构 6.1 随机访问存储器   随机访问存储器(Random-Access Memory,RAM)分为两类:静态的 ...

  3. 002_关于six版本过低报cannot import name urllib_parse的问题

    一. 参考:https://github.com/Parsely/pykafka/issues/222 [root@jyall.com tmp]#python check.py #报错如下 Trace ...

  4. (四)JavaScript 语句

    JavaScript 语句 JavaScript 语句是发给浏览器的命令. 这些命令的作用是告诉浏览器要做的事情. 下面的 JavaScript 语句向 id="demo" 的 H ...

  5. 在Windows .NET平台下使用Memcached (Enyim使用)

    1. 启动并配置Memcached的服务端 1. 下载Memcached  http://download.csdn.net/download/ful1021/7969231 2. 解压到任意目录下, ...

  6. 初学Python——装饰器

    一.什么是装饰器 当我们做好一个产品之后,需要对它进行不断地维护,对某些函数增加一些功能.这个时候如果去修改源代码将是非常不合适的.(原因:1.原则上已经写好的函数尽量不去修改它,因为一旦修改可能会导 ...

  7. glance系列一:glance基础

    一 什么是glance glance即image service,是为虚拟机的创建提供镜像的服务 二 为何要有glance 我们基于openstack是构建基本的Iaas平台对外提供虚拟机,而虚拟机在 ...

  8. __attribute__ 机制详解(一)

    GNU C 的一大特色就是__attribute__ 机制.__attribute__ 可以设置函数属性(Function Attribute).变量属性(Variable Attribute)和类型 ...

  9. JS /javascript 解除网页屏蔽右键(无法复制)的代码

    javascript:(function() { function R(a){ona = "on"+a; if(window.addEventListener) window.ad ...

  10. FineUIMvc v4.0.0 发布了,MVC控件库基础版免费!

    FineUI(MVC版)v4.0.0 已经于 2017-10-24 发布! 这个版本将引入了激动人心的 CSS3 动画,只需要开启全局属性 EnableAnimation 即可,先睹为快: 1. 菜单 ...