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

给定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


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

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

时间: 2024-10-12 02:30:53

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

C++11新特性应用--介绍几个新增的便利算法(不更改容器中元素顺序的算法)

总所周知,C++ STL中有个头文件,名为algorithm,即算法的意思. The header<algorithm>defines a collection of functions especially designed to be used on ranges of elements. 所以,要八一八这个头文件中C++11新增的几个算法,今天主要描述的几个算法不改变容器中元素的顺序. 这里还要啰嗦一句,使用stl算法时,如果与lambda表达式组合使用,那么代码会更加简洁. find_

[经典算法题]寻找数组中第K大的数的方法总结

[经典算法题]寻找数组中第K大的数的方法总结 责任编辑:admin 日期:2012-11-26 字体:[大 中 小] 打印复制链接我要评论 今天看算法分析是,看到一个这样的问题,就是在一堆数据中查找到第k个大的值. 名称是:设计一组N个数,确定其中第k个最大值,这是一个选择问题,当然,解决这个问题的方法很多,本人在网上搜索了一番,查找到以下的方式,决定很好,推荐给大家. 所谓"第(前)k大数问题"指的是在长度为n(n>=k)的乱序数组中S找出从大到小顺序的第(前)k个数的问题.

选择第K个最小元素

作为快速排序的扩展应用,这里介绍一个选择第k个最小元素的问题. 1. 问题描述 给定线性序列中的n个元素和一个整数k, 0<=k<n, 要求找出这n个元素中第k小元素. 2. 求解方法 2.1 直接排序 使用quick sort, 然后选择第k个元素,需要的时间复杂度为O(n*logn). 2.2 利用快速排序思想求解[分治法] 在快速排序中我们用到partition方法每次可以找出中间元素,能够保证左边的元素都比它小,而右边的都比它大.所以可以利用这一点,让我们在O(n)的平均时间内找出第K

A+B Again(在某个数中找大于m的最小约数)

A+B Again Accepted : 15   Submit : 243 Time Limit : 1000 MS   Memory Limit : 65536 KB  题目描述 上次趣味赛小明的a+b坑了不少不喜欢思考的同学,小明为了表示歉意, 这次出了道简单的a+b给大家当签到题,希望大家能开心刷题. 那么,题目来了!!! 求使得b/(a+x)为整数的最小正整数x的值. 输入 第一行是一个整数K(K≤10000),表示样例的个数. 以后每行一个样例,为两个正整数a,b(1≤a,b≤108

xtuoj A+B Again(在某个数中找大于m的最小约数)

新生赛: Accepted : 15   Submit : 243 Time Limit : 1000 MS   Memory Limit : 65536 KB  题目描述 上次趣味赛小明的a+b坑了不少不喜欢思考的同学,小明为了表示歉意, 这次出了道简单的a+b给大家当签到题,希望大家能开心刷题. 那么,题目来了!!! 求使得b/(a+x)为整数的最小正整数x的值. 输入 第一行是一个整数K(K≤10000),表示样例的个数. 以后每行一个样例,为两个正整数a,b(1≤a,b≤108). 输出

php array_rand()函数从数组中随机选择一个或多个元素

php使用array_rand()函数从数组中随机选择一个或多个元素的方法. 使用array_rand() 函数从数组中随机选出一个或多个元素,并返回. array_rand(array,number) 参数 描述 array 必需.规定输入的数组参数. www.jbxue.com number 可选.默认是 1.规定返回多少个随机的元素. 例子: <?php $a=array("a"=>"Dog","b"=>"Cat

javascript如何遍历数组中的每一个元素

javascript如何遍历数组中的每一个元素:遍历数组中的所有元素是一个非常基础简单的操作,可能初学者还不够了解,下面就通过代码实例介绍一下如何实现此功能.代码如下: var theArray=["蚂蚁部落","青岛市南区","新锐科技",3]; for(var index=0;index<theArray.length;index++) { console.log(theArray[index]); } 以上代码可以遍历数组中的每一个元

在一个整型数组中有一个元素的出现次数超过了数组长度的一半,试设计一个 在时间上尽可能高效的算法,找出这个元素。

题目:在一个整型数组中有一个元素的出现次数超过了数组长度的一半,试设计一个 在时间上尽可能高效的算法,找出这个元素.要求:(1)给出算法的基本设计思想.(2)根据设计思想,采用C或C++或Java语言描述算法,关键之处给出注释.(3)说明你所设计算法的时间复杂度和空间复杂度. (1)基本的设计思想: 一个数字出现的次数超过了长度的一半, 那么我们可以这样认为这个数字出现的个数一定大于其他全部数字出现的个数之和.算法的步骤如下: ①设数组为data[],数组长度为n,i=1.置currentAxi

黑马基础阶段测试题:定义一个int类型的数组,数组中元素为{5,7,3,9,4}。求出数组中的最小值,并判断最小值是否为偶数,如果是偶数则输出“最小值为偶数”,如果不是偶数则输出“最小值为奇数”。打印如下:

package com.swift; import java.util.Arrays; public class ArrayTest { public static void main(String[] args) { /* * 定义一个int类型的数组,数组中元素为{5,7,3,9,4}. * 求出数组中的最小值,并判断最小值是否为偶数,如果是偶数则输出"最小值为偶数",如果不是偶数则输出"最小值为奇数".打印如下 */ int arr[]= {5,7,3,9,4