昨天晚上做微软的线上测试,被虐的杠杠的。。。先贴一道题出来,题目如下
重点还是思想,而且一点出来这个思想真的不难。
就是二进制数字排序问题。比如2个1,2个0的时候,排序就是:
0011,0101,0110,1001,1010,1100
仔细推测可以发现,从右到左(低位到高位)来看,若出现01分界线就一定需要交换,并且01的右边都需要头尾依次交换。
拿长一点的数字来举例,01111000下一位数字应该是10000111,其实就是最高两位01交换成10,后面六位,第一位1和最后一位0交换,第二位1和倒数第二位0交换,第三位1和倒数第三为0交换。多举几个例子就会发现这个规律绝对是正确的。
然后还稍微有个问题就是题目中要求k位输入有错要打印impossible,就是怎么判断的问题。代码简单来说就是从第一个数字前面m个0后面n个1开始数,数到第k个数字返回这个数就行了。可是如果k>排序组合数值呢?
一个办法就是计算一下排列组合总数为,K若大于这个值就打印错误,当然比较麻烦;
第二个方法就是判断已数到最大数字,1100这种1都在高位,但是计数还没达到k,输出错误,不过还是要把整个数组都要判断一遍。
最后我用的简单方法是,因为每次找到下一位数字都肯定要交换数字,找到k程序会马上终止,如果还在循环但是没有交换数字,就判断已经达到最大排列组合。代码如下:
#includeusing namespace std;int main(void){ int m,n,k,length,flag=0,temp,impossible=0,number=0; int num[40]; cin>>m>>n>>k; for(int i=0;i 0;i--) { if(num[i]!=num[i-1]) { if (num[i]==1) { temp=num[i]; num[i]=num[i-1]; num[i-1]=temp; for(int j=i+1;j <<"Impossible"< < <