成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

送上今年微軟的一道筆試題

開發 開發工具
這里送上一道微軟的筆試題,大家可能會認為這是一個全排列的問題,但是全排列在問題在于不能很好的知道每個數到底排在第幾位,并且時間上肯定是不能通過的,遞歸的效率大家應該都知道。

這里送上一道微軟的筆試題,具體題目如下:

Time Limit: 10000ms

Case Time Limit: 1000ms

Memory 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 string according to the dictionary order. If s​uch 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”.

 

Sample In

3

2 2 2

2 2 7

4 7 47

Sample Out

0101

Impossible

01010111011

其實說了這么多,意思很簡單,就是輸入N個0,M個1.然后求出由M,N個1,0組成的第K大的數。如果不存在則輸出impossible.

初來乍到的,大家可能會認為這是一個全排列的問題,但是全排列在問題在于不能很好的知道每個數到底排在第幾位,并且時間上肯定是不能通過的,遞歸的效率大家應該都知道。

我們可能會想到另外一種解決方案,直接列舉,從最小的000...1111開始,一直列舉到1111..000然后記錄下當前是否是含N個0,M個1。這種方式是最容易理解的了,但是如果數字比較大,比如17個1,17個0,我們且不說這么大的整數不能保存,就這個時間上也不合算啊,雖然他是線性復雜度,但是這個線性數也太大了點。。。

OK,我接下來又想到了是否可以通過樹的遍歷,想了想被我否了。

終于想到了一種方式,就是通過不斷的交換獲得。我們想到,如果從一個第1大的數變成第2大的數,必然要使這個數增大,那么怎么個增大法?才能使得這兩個數是最接近的,也就是說我們只增加了1,而不是中間還存在很多數呢?

那就是從左到右掃描數據,直到遇到10就交換,并且在該1之前的1要和***位的0交換。好的思路已經完全暴露了,我這里就列舉一個例子。

比如5個1,5個0的情況。

我們保存的格式是1111100000(實際數為0000011111),它是最小的數(輸出的時候倒著輸出,這種結構主要為了理解方便)。***的數是0000011111.(記住,是倒著哈!)

當我們要增加的時候在J=5的時候,出現了0,且j=4時,它為1,這樣就交換他們,j=4之前的1和低位的0交換,這里沒有0就不需要交換了。得到1111010000(實際數為0000101111).

當我們出現0011101100(實際數為0011011100)要使數字增加1應該怎么做呢?顯然,還是J=5時出現了0且j-1=4時為1交換他們,并且j=4之前的1和***位的0開始不斷交換,***我們會得到結果:1100011100.(實際數為00111000011).

Ok,說到這里大家應該就完全懂了,且看算法源代碼:[集思廣益,你們有沒有更好的解決方案?]

  1. //M:0的個數,N,1的個數。K要輸出第幾個數。 
  2. bool test(int N,int M,int K){ 
  3.     if(calculateTotalNum(M+N,M)<K)//若實際上的數少于k,返回false,則輸出impossible 
  4.         return false
  5.     int L=M+N,count=1
  6.     bitset<MaxLength> bit; 
  7.     map<int,bitset<MaxLength>> mapStr; 
  8.     for(int i=0;i<M;i++)//初始話最小數,即0都在最左邊比如0011 
  9.         bit[i]=1
  10.     if(K==1){ 
  11.         print(bit,M+N);//輸出 
  12.         return true
  13.     } 
  14.     int j=0;//表示從低位一直搜索到高位,有沒有遇到01,有的話就不斷交換。 
  15.     while(!isLast(bit,M,N)){//沒有搜索到***一個數字 
  16.         if(j>=M+N-1
  17.             j=0;//已經搜索到***位了,這個時候就需要從0位搜索 
  18.         if(1==bit[j]&&0==bit[j+1]){ 
  19.             int right=j-1,left=0
  20.             //從J的前一個搜素,并且該之前的1全部移動到最左邊 
  21.             while(right>=0&&bit[right]==1&&left<right){ 
  22.                 bool temp=bit[right]; 
  23.                 bit[right]=bit[left]; 
  24.                 bit[left]=temp; 
  25.                 right--,left++; 
  26.             } 
  27.             bit[j]=0;//交換0,1 
  28.             bit[j+1]=1
  29.             count++;//統計是第幾個大的數了 
  30.             if(count==K){ 
  31.                 print(bit,M+N); 
  32.                 return true
  33.             } 
  34.             j=0;//重新回過頭來搜素 
  35.         } 
  36.         else 
  37.             j++; 
  38.     } 
  39.     return true
  40.  
  41. int calculateTotalNum(int N,int M){//組合問題,計算一共多少個數。C(M,N)=A(N,N)/(A(M,M)*A(N-M,N-M)) 
  42.     int result=1
  43.     for(int i=1;i<=N;i++) 
  44.         result*=i; 
  45.     for(int i=1;i<=M;i++) 
  46.         result/=i; 
  47.     for(int i=1;i<=N-M;i++) 
  48.         result/=i; 
  49.     return result; 
  50. bool isLast(bitset<MaxLength> bit,int M,int N){ 
  51.     int i=0
  52.     while(i<N&&0==bit[i]) 
  53.         i++; 
  54.     if(i==N) 
  55.         return true
  56.     else 
  57.         return false
  58. void print(bitset<MaxLength> bit,int N){// 
  59.     for(int i=N-1;i>=0;i--) 
  60.         cout<<bit[i]; 
  61.     cout<<"  "

 附上效果截圖:

 [庸男勿擾] 同學提供了一種其他的解決方式,主要是通過遞歸的判斷當前0,1組合生成的個數與K進行比較。

(保證在不減一個0時,生成的組合總數是大于K的,否則return。)

若當前0的個數減一后,生成的總數要大于K,則輸出0,同時0的個數減一,K,1的個數不變。

若當前0的個數減一后,生成的總數小于K,則輸出1,同時1的個數減一,0的個數不變,K=K-當前總數。

遞歸調用。***能得到結果。

代碼 [庸男勿擾] 已經貼出,在回答留言處!

[有一個問題是,我和庸男勿擾在計算總次數的時候都會有溢出的問題,即使用Long long也會溢出的,大家在計算階乘或者組合問題對溢出解決方案有什么好的建議可以給出嗎?] 

原文鏈接:http://www.cnblogs.com/xiaoyi115/p/3696507.html

責任編輯:林師授 來源: 博客園
相關推薦

2021-05-09 19:42:25

筆試題前端算法

2021-04-30 08:22:36

異步求和函數

2024-10-11 17:09:27

2009-06-22 13:43:00

java算法

2011-05-23 11:27:32

面試題面試java

2018-03-06 15:30:47

Java面試題

2009-08-11 10:12:07

C#算法

2023-02-04 18:24:10

SeataJava業務

2012-07-03 09:38:42

前端

2009-08-11 14:59:57

一道面試題C#算法

2021-01-26 13:14:14

js前端map

2021-05-31 07:55:44

smartRepeatJavaScript函數

2017-11-21 12:15:27

數據庫面試題SQL

2022-04-08 07:52:17

CSS面試題HTML

2009-08-11 15:09:44

一道面試題C#算法

2024-03-18 13:32:11

2023-08-01 08:10:46

內存緩存

2010-08-11 11:57:02

微軟筆試題微軟筆試題

2021-03-16 05:44:26

JVM面試題運行時數據

2021-10-28 11:40:58

回文鏈表面試題數據結構
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 国产精品九九九 | 亚洲自拍偷拍视频 | 91一区 | 免费观看一级特黄欧美大片 | 精品视频在线观看 | 天天久久 | 国产99视频精品免费播放照片 | 一区二区三区精品视频 | 亚洲欧美日韩精品久久亚洲区 | 妖精视频一区二区三区 | 黄色三级免费网站 | 日韩成人av在线 | 日韩中文字幕视频 | 国产免费色| 精品亚洲一区二区 | 91免费小视频 | 欧美亚洲国产日韩 | 99久久国产精 | 免费成人在线网 | 久久久久久综合 | 久久久久99 | 久久99精品视频 | 欧美日韩久 | 久久久久久99 | 国产一区二区三区四区在线观看 | 久久久夜色精品亚洲 | 99视频免费播放 | 国产激情精品视频 | 自拍偷拍亚洲欧美 | 国产一二区免费视频 | 国产精品国产馆在线真实露脸 | 国产一区二区三区 | 秋霞精品 | 羞羞视频免费观 | 精品亚洲永久免费精品 | 久久影音先锋 | 国产精品久久精品 | 亚洲精品第一页 | 日韩乱码在线 | 成人在线免费观看 | 亚洲欧美国产视频 |