码迷,mamicode.com
首页 > 其他好文 > 详细

[算法]请用A中元素组成一个大于k的最小正整数

时间:2014-07-09 15:28:59      阅读:131      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   使用   width   

给定A[]={0,1,3,8},A是U={0,1,2,3,4,5,6,7,8,9}的子集,k是正整数,请用A中的元素组成一个大于k的最小正整数。

思路:

1、使用flag数组标记A中的元素,

bool flag[10];

顺便记录A中的最小元素

bool flag[10] = {0,0,0,0,0,0,0,0,0,0};
int min = 10;
for(int i = 0; i < n; ++i){
    flag[a[i]] = true;
    min = min < a[i] ? min : a[i];
}

 

2、使用bound数组表示:bound[i]表示比i大,且在A中的最小元素,倘若在A中找不到比i大的元素,则令bound[i]=10

如A={0,1,3,8}对应的bound[] = {1,3,8,8,8,8,8,8,8,10,10};

int bound[10];
for(int i = 0, j; i < 10; ++i){
    for(j = i; j < 10 && !flag[j]; ++j);
    if(j == i){
        for(j = i+1; j < 10 && !flag[j]; ++j);
    }
    bound[i] = j;
}

 

3、将k转换为数组num表示,length记录数组长度

int num[maxSize];
int j = maxSize;
num[--j] = k % 10;
k /= 10;
while(k){
    num[--j] = k % 10;
    k /= 10;
}
int i = 0;
while(j < maxSize){
    num[i++] = num[j++];
}
int length = i;

 

4、从k的最高位向最低位遍历,即从数组num从头遍历,result[]记录所求的最小正整数各位

4.1若num[i]在A中,即flag[num[i]]为真,

    若num[i]不是k的个位数上的数字,将num[i]写入result,

    若num[i]是k的个位数上的数字,

      若bound[num[i]] < 10,将bound[num[i]]写入result

      否则转向4.3

  否则转4.2

4.2若bound[num[i]] < 10,即A中有比num[i]大的数,bound[num[i]]写入result,然后将result的剩余位数全部置为min。

4.3若bound[num[i]] =10,即A中没有比num[i]大的数,即返回修改result,转向4.4

4.4从当前位置往k的高位数遍历,即从当前位置num[i] 往 num[0]遍历,找出使用bound[num[i]] < 10成立的bound[num[i]],然后修改result,并并将后续的改为min;倘若bound[num[i]] < 10一直不成立,则表示大于k的最小正整数的位数比k多一位,将最高的两位置为A能表示的最小的两位数,剩下的使用min充填即可。

 

int result[maxSize],len;
    for(int i = 0; i < length; ++i){
        if(flag[num[i]]){
            if(i != length-1){
                result[i] = num[i];
            }
            else{
                if(bound[num[i]] < 10){
                    result[i] = bound[num[i]];
                    len = length;
                }
                else{
                    len = fill_rest(bound,result,num, length,i,min);
                }
            }
        }
        else{
            if(bound[num[i]] < 10){
                result[i] = bound[num[i]];
                while(++i < length){
                    result[i] = min;
                }
                len = length;
            }
            else{
                len = fill_rest(bound,result,num, length,i,min);
            }
            break;
        }
    }
int fill_rest(int* bound, int* result, int* num, int length, int i, int min){
    while(--i >= 0 && bound[num[i]] == 10);
    if(i >= 0){
        result[i] = bound[num[i]];
        while(++i < length){
            result[i] = min;    
        }
        return length;
    }
    else{
        if(min){
            result[++i] = min;
        }
        else{
            result[++i] = bound[min];
        }
        while( ++i <= length){
            result[i] = min;
        }
        return length+1;
    }
} 

 

最后将result转为正整数返回

int sum = 0;
for(int i = 0; i < len; ++i){
    sum *= 10;
    sum += result[i];
}
return sum;

 

 

 参考文献

http://www.cnblogs.com/chonghui1001/archive/2011/09/25/2190394.html

 

bubuko.com,布布扣
本文基于知识共享署名-非商业性使用 3.0 许可协议进行许可。欢迎转载、演绎,但是必须保留本文的署名林羽飞扬,若需咨询,请给我发信

[算法]请用A中元素组成一个大于k的最小正整数,布布扣,bubuko.com

[算法]请用A中元素组成一个大于k的最小正整数

标签:style   blog   http   color   使用   width   

原文地址:http://www.cnblogs.com/zhengyuhong/p/3832134.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!