您的位置:首页 > 其它

微软2014实习生在线测试题:K-th String

2014-06-15 22:29 375 查看
原题是有N个0和M个1组成序列(2 <= N + M <= 33 and N , M >= 0),按字典序排列,求出第K个串,若K超出则输出Impossible;

其实就是全排列,并从小到大的顺序排列,求第K个。

首先判断K是否超出,计算N个0和M个1组成全排列有total=种,若K>a则超出。

total个全排列中,前a=

种是第一位为0,即第一位为0,其余M+N-1位是N-1个0和M个1组成全排列,所以判断a和K的关系就可以断定第一位是0还是1,若a>=K,则第一位是0;若a<K,则第一位是1,则求N个0和M-1个1组成全排列中的第K-a个串。依此循环。。。。

代码:

#include<iostream>
#include<string>
using namespace std;
int getTotalNumber(int n,int m)//C M(M+N)
{
int all=n+m;
int total=1;
for(int i=all;i>n;i--)
total*=i;
for(int j=m;j>1;j--)
total=total/j;
return total;

}

int main()
{
//cout<<getTotalNumber(-1,3)<<","<<getTotalNumber(3,1)<<endl;

int caseNum;
cin>>caseNum;
int n,m,k;
for(int c=0;c<caseNum;c++)
{
cin>>n>>m>>k;
if(getTotalNumber(n,m)<k||k<=0)
{
cout<<"Impossible"<<endl;
continue;
}
while(n>=1||m>=1)
{
int a=getTotalNumber(n-1,m);
if(a>=k)
{
cout<<"0";
n--;
}
else
{
cout<<"1";
m--;
k=k-a;
}
}
cout<<endl;
}
return 0;
}


提交后提示Wrong Answer,但得50分,当时怎么也没想通哪些测试用例会出错。

今天做leetcode上的Unique Paths,意思是从m*n的格子的坐上顶端走到右下底端所有的路径数,组合数学里学的,总共要走m-1次的向下一步和n-1次的向右一步,也就是从m+n-2次总选出m-1次的向下一步,共有

种。 把上面的getTotalNumber函数copy一下再改改 提交,发现(10,10)时出错,int越界?
把 total改成 long long型,再linux 上用g++编译(VC 6.0不支持long long),(10,10)的输出结果正确了,再提交,(23,12)错误,我的程序输出的是0,再加个m和n比大小,让m成为较小者,进一步降低total的值,再提交,通过!

由此,K-th String的问题也清楚了,是因为int越界,使得较大的N和M测试用例测试失败,

修改

int getTotalNumber(int n,int m)//C M(M+N)
{
if(m>n)
{
int tmp=m;
m=n;
n=tmp;
}
int all=n+m;
long long total=1;
for(int i=all;i>n;i--)
total*=i;
for(int j=m;j>1;j--)
total=total/j;
return total;
}
应该可以通过了!
转自我的搜狐博客 http://jluhlh.blog.sohu.com/302327975.html
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: