[微软实习生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大的,这么递归下去即可。

  代码如下:

 1 #include <iostream>
2
3 using namespace std;
4
5 int jiecheng(int n)
6 {
7 if(n==1 || n==0) return 1;
8 return n*jiecheng(n-1);
9 }
10
11 int allNum(int n,int m)
12 {
13 return jiecheng(n+m)/(jiecheng(n)*jiecheng(m));
14 }
15
16 void fun(int n,int m,int k)
17 {
18 int znum;
19 if(k>allNum(n,m)) return;
20 if(n==0)
21 znum=0;
22 else
23 znum = allNum(n-1,m);
24 if(m==0 && n==0)
25 return;
26 if(m==0 && n!=0)
27 {
28 for(int i=0; i<n; i++)
29 cout<<"0";
30 return;
31 }
32 if(k>znum)//在以1开头的里面
33 {
34 cout<<"1";
35 fun(n,m-1,k-znum);
36 }
37 else
38 {
39 cout<<"0";
40 fun(n-1,m,k);
41 }
42 }
43 int main()
44 {
45 int T;
46 int N,M,K;
47 int total;
48 cin>>T;
49 while(T--)
50 {
51 cin>>N>>M>>K;
52 if(N==0 && M==0)
53 {
54 cout<<"Impossible"<<endl;
55 continue;
56 }
57 if(N!=0 && M==0 && K==1)
58 {
59 for(int i=0; i<N; i++)
60 cout<<"0";
61 cout<<endl;
62 continue;
63 }
64 total = allNum(N,M);
65 if(K>total)
66 {
67 cout<<"Impossible"<<endl;
68 continue;
69 }
70 fun(N,M,K);
71 cout<<endl;
72 }
73 return 0;
74 }

  ps:这个代码比较丑陋,有一个重要的问题是,当N+M很大时,(N+M)!/(N!*M!)会超出int的表示范围,这时候需要用一些其他的高精度类型来表示,这算是本题的一个陷阱,不是核心内容,具体不表。

时间: 2024-08-01 06:32:40

[微软实习生2014]K-th string的相关文章

微软2014实习生在线测试之K-th string

问题描述: Time Limit: 10000msCase Time Limit: 1000msMemory Limit: 256MB 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 str

2014微软实习生面试经历

28号结束了最后的三面.因为三个面试官都没有要求我对面试内容保密,所以现在就将自己面试微软的整个过程记录为博文,供以后的面试者作为参考.转载请注明出处:http://blog.csdn.net/xiefubao. 开学的时候了解到微软今年在西安没有宣讲会和笔试现场,以为微软不准备在西安招人了.后来才在官网看到今年是网上笔试.大概是3月底投的简历,中文简历早就准备好了,当时临时赶了一份很粗糙的英文简历.四月初收到了第一轮笔试的通知.第一轮笔试2个小时,四道英文编程题目,难度要比ACM简单.当时做的

微软 WPC 2014 合作伙伴keynote

本周一,2014 微软WPC (Worldwide Partner Conference) 合作者伙伴大会在美国华盛顿开幕,微软除了介绍了Azure.云端化的Office 365和Windows Phone移动平台之外,还简单提及了下一代Windows操作系统Windows 9的发展规划. 做为微软金牌合作伙伴的葡萄城控件,我们一直非常关注微软技术的发展趋势,下面就WPC 2014 Keynote进行分享: Windows:   最新数据显示,Windows占据着90%的PC市场:而在广阔的个人

微软发布2014年7月的安全公告 安全狗建议及时修复

软准时发布2014年7月的安全公告,主要修复了IE浏览器.以及Windows组件中存在的多个安全漏洞(总计达29枚).包括远程执行代码.特权提升和拒绝服务等类型.服务器安全狗也已经推送了这批补丁,为避免黑客利用最新漏洞进行攻击,安全狗建议大家及时修复,以防被黑客入侵! 以下附上2014年7月安全漏洞摘要: 1.MS14-038:Windows 日记本中的漏洞可能允许远程执行代码(KB2971850) 描述:此安全更新可解决Microsoft Windows中一个秘密报告的漏洞.如果用户打开特制日

【模拟】NCPC 2014 K Train passengers

题目链接: http://acm.csu.edu.cn/OnlineJudge/problem.php?id=1797 题目大意: 有N个车站,火车一共可以坐M个人,每个车站下车Ai,上车Bi个人,在车站等待下一班Ci个人.问输入是否合法. 合法:火车上的人不超过M,第一站不能有人下车,最后一站不能有人上车,火车满的时候才能有人在车站等下一班. 题目思路: [图论] 签到水题.模拟到达每个车站的状态即可. 1 // 2 //by coolxxx 3 //#include<bits/stdc++.

微软校招编程题&quot;Beautiful String&quot;的状态机解法

昨天碰巧看到一道微软校招的编程题,题目大意如下: 如果一个字符串包括三组或者更多组的连续升序字母,每组长度相等,那么我们就称这个字符串是Beautiful String 如下是一些Beautiful String的例子: abc.cde.aabbcc.aaabbbccc 这些不是Beautiful String: abd.cba.aabbc.zab 输入一个只含有小写字母的字符串,如果它含有一个Beautiful的子串,就输出YES,否则输出NO 输入: 第一行是案例个数,之后的每一行是一个数字

hdu4862 2014多校B题/ 费用流(最优情况下用不大于K条路径覆盖)(不同的解法)

题意: 一个数字矩阵,可以出发K次,每次可以从右边或者下面走,要求(在收益最大情况下)覆盖全图,不能则输出-1.(规则:每次跳一步的时候若格子数字相等则获得该数字的能量,每跳一步消耗距离的能量).每个格子走且仅能走一次. 选<=K条路径,最优情况来覆盖全图. 显然用拆点为二分图. 一种解法:边(流量,费用) 源点向X部连边(1,0)Y部向汇点连边(1,0)X到Y,若能到,则有边(1,消耗-获得).关键点(解决每个点都覆盖,恰好起到填补的作用):在X部最上面添加一个点,源点连之(k,0)它向所有Y

微软 Windows 10 将支持 8 英寸以下 ARM 平板设备

2015 年 1 月 24 日,  9:32 下午 - 微软本周展示了 Windows 10 一系列新的改变,也包括首次公开展示的 Windows 10 手机版,但 ARM 平板并没有得到太多提及. 而且微软官方也确认驱动 ARM 平板的 Windows RT 操作系统将只有“特殊更新提供部分 Windows 10 功能”,意味着现有 Surface RT 和 Surface 2 和 Lumia 2550 用户可能享受不到 Windows 10 完整系统功能. 不过微软仍会支持 ARM 平板设备

微软Visual Studio &quot;14&quot; CTP 2 发布

对于在微软阵营下进行工作的团队来说,拥有最新版本的Visual Studio是提高效率最佳的选择,没有之一. 在本文中,我们就上个月发布的Visual Studio "14" CTP1和昨天发布的Visual Studio "14" CTP2进行详细发布说明梳理,供大家餐食: (一) Visual Studio "14" CTP 2版本: 微软于2014年7月8日发布了Visual Studio 14 (新Visual Studio版本的代号)的