数字问题---位数上的数字
【座右銘】1. 想要成為行家,就必須嘗試解決大量的問題;
? ? ? ? ? ? ? ? ? ? 2. 解決大量問題并不代表能解決所有問題,而是表示解決下一個問題的幾率變大了
1.?已知一個整數集合T,集合中可以包括0到9之間任意數,集合中數字不重復。現在給出一個整數N,大小按int類型,算法要求是:從上面集合中取出數字所能組成的整數中,比給出的N大的集合里面,?最小的那個整數。比如,整數集合T=『1,2,3』,整數N=300,那么要從集合中取出數字所組成的整數應該是311;再如:T=『1』,N=56,那么要得到的整數應該是111(也就是說集合里面的?數可以取多次);【問題來源于論壇】
第一部分:
思路一: 從小到大遍歷[N+1, IntegerMax],找出滿足所有數字在集合T中的第一個整數
思路二:對整數N,從N的最高位向最低位掃描,求出滿足條件的整數M
1)若Ni位不是最后1位,且在集合T中出現,則Mi=Ni
2)若Ni位是最后1位,或者不在集合T中出現,則
2.1) 若集合T中存在大于Ni且最小的數字a,讓Mi=a。然后讓余下的位置(比i位要低的位置)都取T中的最小值
2.2) 若集合T中不存在大于Ni的數字,則對Mi-1位進行處理。找出比Mi-1位數字大的且在集合T中的元素,若Mi-1位仍不滿足,則繼續前進找Mi-2位,直到滿足條件為止(最壞情況下多補1個最高位)。然后將余下的位置(比滿足條件的位置要低的位置)都取T中的最小值
第二部分:
//java代碼,T為集合,len為集合T中元素個數,N為整數
//不考慮異常情況:例如N為負數,或者是整數最大值
public static int greater(int[] T, int len, int N){//初始化集合Tboolean[] set = new boolean[10];int min = 10;for(int i=0;i<len;i++){min = (min>T[i])? T[i]:min;set[T[i]] = true;}//初始化Aifinal int IntegerLen = 11;int[] source = new int[IntegerLen];int j = 0;if(N==0){source[j++] = 0;}else{while(N>0){source[j++] = N%10;N /= 10;}}j--;int[] target = new int[IntegerLen];int k = 1; //預留一位while(j>=0){if(j!=0&&set[source[j]]){//若Ni位在集合T中存在,則Mi=Nitarget[k++] = source[j];j--;}else{//在集合T中選取一個比Ni大且最小的數字int bigger = -1;for(int p=source[j]+1;p<10;p++){if(set[p]){bigger = p;break;}}if(bigger!=-1) //找到{target[k++] = bigger;j--;}else //未找到{int dis = k;k--;boolean flag = false;while(!flag){for(int p=target[k]+1;p<10;p++){if(set[p]){flag = true;target[k++] = p;break;}}if(!flag){k--;}}j += (dis - k);}//后面的數都取集合T中的最小值while(j-->=0){target[k++] = min;}}}//組成新的數字int M = target[0];int position = 0;while(++position<k){M *= 10;M += target[position];}return M;}第三部分: 測試用例
T = {9,2,3}, N = 0: M = 2
T = {1,2,3}, N = 2: M = 3
T = {1,2,3}, N = 4: M = 11
T = {1,2,3}, N = 23: M = 31
T = {1,2,3}, N = 33: M = 111
T = {1,2,3,9}, N = 9999: M = 11111
2.?有這樣一種編碼:如,N=134,M=f(N)=143,N=020,M=fun(N)=101,其中N和M的位數一樣,N,M可以均可以以0開頭,N,M的各位數之和要相等,即1+3+4=1+4+3,且M是大于N中最小的一個,現在求這樣的序列S,N為一個定值,其中S(0)=N,S(1)=fun(N),S(2)=fun(S(1))。【問題來源于v_JULY_v的博客:http://blog.csdn.net/v_july_v/article/details/6855788】
第一部分:
思路一: 從小到大遍歷[N+1, IntegerMax],找出滿足數字和相同的第一個整數
思路二:從低位往高位掃描
1)從低位往高位掃描,找出第一位大于0的位數i的數字a,將該位賦值0,將未分配的數字和T加上a-1,即T=T+a-1。將第i-1位(比i位高1位)數字b加1
1.1)若第i-1位的數字b<10,進入第2步
1.2)若第i-1位的數字b=10,則將該位賦值0,且T=T+9;將第i-2位數字c加1。直至找到滿足條件的位置(最壞情況下多增加1位),進入第2步
2)將T從最低位向高位分配,直至T=0。分配原則為:小于等于9,全部放在當前配置;大于9,給當前位置放9
第二部分:
//java代碼,參數說明:N為整數
//不考慮異常情況:如N負數,或者為0
public static int next(int N){//求出數字和final int IntegerLen = 10;int[] source = new int[IntegerLen];int i = 0, sum = 0;while(N>0){source[i] = N%10;sum += source[i];i++;N /= 10;}//從地位向高位走int j = 0;while(source[j]==0){j++;}//把高1位的位置加1int total = source[j]-1;source[j] = 0;j++;while(true){if(source[j]==9){source[j++] = 0;total += 9;}else{source[j]++;break;}}//將數從地位向高位分配int k = 0;while(total!=0){if(total<=9){source[k] = total;total = 0;}else{source[k++] = 9;total -= 9;}}//組合新數字int M = 0;for(int p=IntegerLen-1;p>=0;p--){M *= 10;M += source[p];}return M;}第三部分:測試用例N = 1: M = 10
N = 10: M = 100;
N = 20: M = 101;
N = 101: M = 110;
N = 110: M = 200;
N = 99: M = 189
總結
以上是生活随笔為你收集整理的数字问题---位数上的数字的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数学家在举世瞩目的成就背后,经历了怎样的
- 下一篇: 拉灯问题c语言编程,行测答题技巧:数量关