[微软实习生2014]K-th string
很久之前的事情了,微软2014实习生的在线测试题,记录下来以备后用。
题目描述:
Description
Consider a string set that each of them consists of {0, 1} only. All strings in the set have the same number of 0s and 1s. Write a program to find and output the K-th string according to the dictionary order. If such a string doesn’t exist, or the input is not valid, please output “Impossible”. For example, if we have two ‘0’s and two ‘1’s, we will have a set with 6 different strings, {0011, 0101, 0110, 1001, 1010, 1100}, and the 4th string is 1001.
Input
The first line of the input file contains a single integer t (1 ≤ t ≤ 10000), the number of test cases, followed by the input data for each test case.
Each test case is 3 integers separated by blank space: N, M(2 <= N + M <= 33 and N , M >= 0), K(1 <= K <= 1000000000). N stands for the number of ‘0’s, M stands for the number of ‘1’s, and K stands for the K-th of string in the set that needs to be printed as output.
Output
For each case, print exactly one line. If the string exists, please print it, otherwise print “Impossible”.
样例输入
3
2 2 2
2 2 7
4 7 47
样例输出
0101
Impossible
01010111011
题解:
这道题目本身不是很难,题目的大概意思是让我们从N个0、M个1组成的二进制数从小到大排列中找出第k个。话虽这么说,但事实上肯定不能这么做,N和M虽然不大(最大到33),但其排列组合的规模依然非常可观,暴力法的时间消耗是不能接受的。
说说我的想法吧。首先从0、1排列的那些数从小到大的排列中,一个很显然的是第一个数是0的肯定比第一个数是1的要小,而且我们要找的那个第k个数,要么在首位为0的那一拨里,要么在首位为1的那一拨里,也就是说,我们只要比较首位为0的数的个数与k的大小,就知道应该是属于哪一拨!至于怎么计算首位为0的数的个数,这是排列组合的基本知识。首先N个0和M个1组成的所有数的数目为(N+M)!/(N!*M!),那么,固定首位为0,就是求N-1个0和M个1组成的所有数的数目,即(N-1+M)!/((N-1)!*M!)
有了这个基本的想法,我们接下来只要递归得做这样一件事情就行。以题中的输入2 2 2为例,对于初始情形,2个0和2个1共有6种组合,其中第一位为0的有3个,由k小于3,所以肯定这个数在首位为0的那一拨里,这时就可以输出第一位“0”,如果这里k大于3,那么输出首位为“1”,并在首位为1的那一拨里找第k-3大的,这么递归下去即可。
代码如下:
#include <iostream> using namespace std; int jiecheng(int n)
{
if(n== || n==) return ;
return n*jiecheng(n-);
} int allNum(int n,int m)
{
return jiecheng(n+m)/(jiecheng(n)*jiecheng(m));
} void fun(int n,int m,int k)
{
int znum;
if(k>allNum(n,m)) return;
if(n==)
znum=;
else
znum = allNum(n-,m);
if(m== && n==)
return;
if(m== && n!=)
{
for(int i=; i<n; i++)
cout<<"";
return;
}
if(k>znum)//在以1开头的里面
{
cout<<"";
fun(n,m-,k-znum);
}
else
{
cout<<"";
fun(n-,m,k);
}
}
int main()
{
int T;
int N,M,K;
int total;
cin>>T;
while(T--)
{
cin>>N>>M>>K;
if(N== && M==)
{
cout<<"Impossible"<<endl;
continue;
}
if(N!= && M== && K==)
{
for(int i=; i<N; i++)
cout<<"";
cout<<endl;
continue;
}
total = allNum(N,M);
if(K>total)
{
cout<<"Impossible"<<endl;
continue;
}
fun(N,M,K);
cout<<endl;
}
return ;
}
ps:这个代码比较丑陋,有一个重要的问题是,当N+M很大时,(N+M)!/(N!*M!)会超出int的表示范围,这时候需要用一些其他的高精度类型来表示,这算是本题的一个陷阱,不是核心内容,具体不表。
[微软实习生2014]K-th string的更多相关文章
- 微软 Build 2014开发者大会干货整理-1
微软 Build 2014开发者大会第二天的主题演讲主要包含两部分:Microsoft Azure的发展状况,以及 .NET和生态系统的发展介绍.第二天的重点整理也由此分为上下两部分.您可以在Chan ...
- 【模拟】NCPC 2014 K Train passengers
题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1797 题目大意: 有N个车站,火车一共可以坐M个人,每个车站下车Ai,上车Bi个人,在 ...
- 微软 WPC 2014 合作伙伴keynote
本周一,2014 微软WPC (Worldwide Partner Conference) 合作者伙伴大会在美国华盛顿开幕,微软除了介绍了Azure.云端化的Office 365和Windows Ph ...
- 【笔试】T实习生2014 总结
2014.4.12 是T的广州站,就在本校,很方便.考前一两天,临时抱佛脚,看着HTMLdog上的网页知识.就算考前,还在懊悔自己为什么不好好利用清明假期,多看点,看多点?哎,哎.. 谁知道一拿到试卷 ...
- [Swift]LeetCode358. 按距离为k隔离重排字符串 $ Rearrange String k Distance Apart
Given a non-empty string str and an integer k, rearrange the string such that the same characters ar ...
- hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)
题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1.(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量).每个 ...
- LC 358. Rearrange String k Distance Apart
Given a non-empty string s and an integer k, rearrange the string such that the same characters are ...
- 剑指Offer面试题:27.最小的k个数
一.题目:最小的k个数 题目:输入n个整数,找出其中最小的k个数.例如输入4.5.1.6.2.7.3.8这8个数字,则最小的4个数字是1.2.3.4. 这道题是典型的TopK问题,其最简单的思路莫过于 ...
- golang中string以及slice之间的一些问题
好记性不如烂笔头o_O slice切片不会开辟新的空间 a := []int{0,1,2,3} b := make([]int, 8) b = a[:] b[2] = 9 fmt.Println(a) ...
随机推荐
- 查看服务器的TCP/IP(http)连接情况
6.那具体到,怎样监听一个具体程序的TCP/IP连接情况呢???!! 就要用:netstat -n|grep 80 命令来查看具体端口对应程序的TCP/IP连接情况了 netstat -n|grep ...
- 百度全新的ARM架构服务器,一个2U机箱装6台,每台4个3T硬盘,每个机箱共72TB
1月11日,中国科学院原秘书长.国家科技重大专项国务院咨询评估组专家侯自强,来到百度南京数据中心,和他一起的还有中国工程院院士倪光南以及工业和信息化部电信研究院传输研究所副所长石友康等人.他们看到的是 ...
- go的优缺点
1.1 不允许左花括号另起一行1.2 编译器莫名其妙地给行尾加上分号1.3 极度强调编译速度,不惜放弃本应提供的功能1.4 错误处理机制太原始1.5 垃圾回收器(GC)不完善.有重大缺陷1.6 禁止未 ...
- java:线程的简单控制方法
中断线程方法 休眠:sleep(); 主动让出cpu:yield(); 设置线程优先级: 取值:getPriority(); 设置:setPriority(..); MAX_PRIORITY最大优先级 ...
- HDU5087——Revenge of LIS II(BestCoder Round #16)
Revenge of LIS II Problem DescriptionIn computer science, the longest increasing subsequence problem ...
- 在java程序中访问windows有用户名和密码保护的共享目录
在java程序中访问windows有用户名和密码保护的共享目录 Posted on 2015-11-20 14:03 云自无心水自闲 阅读(3744) 评论(0) 编辑 收藏 --> Jav ...
- 转ATL对象类型
http://hi.baidu.com/rural_child/item/d91ce5d8fba9c8e73cc2cbf9 1.Objects a.Simple Object:用于实现业务逻辑,无用户 ...
- git全局配置
使用git的童鞋都知道,git是非常好的版本管理工具,工具再好要想用的得心应手还是要下凡功夫的,比如可以通过对git的全局配置文件.gitconfig进行适当的配置,可以在日常项目开发中节省很多的时间 ...
- java服务器知识
http://blog.csdn.net/chenyi8888/article/details/4484641 http://blog.csdn.net/chenyi8888/article/deta ...
- UVa 1328 (KMP求字符串周期) Period
当初学KMP的时候也做过这道题,现在看来还是刘汝佳的代码要精简一些,毕竟代码越短越好记,越不容易出错. 而且KMP的递推失配函数的代码风格和后面的Aho-Corasick自动机求失配函数的代码风格也是 ...