一道整数求值作业

题目描述:给定一个整数 X,找到组成的数字和 X 完全相同的,且大于 X 的最小的那个数。

  • 输入要求

一个整数 X,不会以0开头。

  • 输出要求

输出与 X 数字组成完全相同,且大于 X 的最小的数。若不存在这样的数,输出 0

  • 例如,输入 156 输出 165,或者 27711 就是 71127,330 的话就是 0

思路:题目有三大约束:a. 组成与 X 相同  b. 大于 X  c. 最小

针对 a,可以交换 X 的各个位;对于 b,变动的最高位必须比原来大;对于 c,变动的最高位越接近个位越好

1. 暴力法

穷举所有可能的数,然后在大于 X 的里面找最小

2. 反向扫描

从个位开始逆向遍历,向后扫描,找出比自己大的所有位,选择其中最小的,交换之,然后排序,done

如字符串 s="263861",序号为 0~5
s[4] = 6,后面没有比自己大的
s[3] = 8,同上
s[2] = 3,后面比自己大但最小的数是 6,交换 s[2]和s[4]
从小到大排序 s[3]~s[5]
所以,最终结果为 266138

实现:

#!/usr/bin/env python
#coding=utf8

def test(num):
    text = str(num)
    rtext = list(text[::-1]) #反转字符串以方便遍历
    for i in xrange(1, len(rtext)):
        if rtext[i] < rtext[i-1]: #减少无效比较次数
            gts = [x for x in rtext[:i] if x > rtext[i]] #找到比自己大的所有数
            j = rtext.index(min(gts)) #选择其中最小的
            rtext[i], rtext[j] = rtext[j], rtext[i] #交换之
            ret = sorted(rtext[:i], reverse=True) + rtext[i:] #排序
            return ‘‘.join(ret[::-1])
    return ‘0‘

if __name__ == "__main__":
    from timeit import Timer
    num = input("Input a number: ")
    t1 = Timer("test(num)", "from __main__ import test, num")
    print t1.timeit(1000) #运行1000次所需秒数
时间: 2024-08-27 13:34:08

一道整数求值作业的相关文章

数据结构 -- 整数算术表达式求值 (C/C++)

数据结构题集(C语言版)--严蔚敏,吴伟民编著 设置运算符栈和运算数栈辅助分析运算符有限关系. 读入表达式的字符序列的同时完成运算符和运算数(整数)的识别处理,以及相应的运算. 在识别出运算数的同时,要将其字符序列形式转换成整数形式. 1 /** 2 Function:整数算术表达式求值 3 Date:2014-11-10 4 Author:JackDawson 5 Compiler:gcc version 4.8.1 6 */ 7 #include <iostream> 8 #include

递推求值【快速幂矩阵】

递推求值 描述 给你一个递推公式: f(x)=a*f(x-2)+b*f(x-1)+c 并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值. 注意:-1对3取模后等于2   输入 第一行是一个整数T,表示测试数据的组数(T<=10000)随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值.其中0<=f(1),f(2)<100,-100<=a,b,c<=100,1<=n<=10000000

【蓝桥杯】历届试题 公式求值

  历届试题 公式求值   时间限制:1.0s   内存限制:256.0MB 问题描述 输入n, m, k,输出下面公式的值. 其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数.组合数的计算公式如下. 输入格式 输入的第一行包含一个整数n:第二行包含一个整数m,第三行包含一个整数k. 输出格式 计算上面公式的值,由于答案非常大,请输出这个值除以999101的余数. 样例输入 313 样例输出 162 样例输入 201010 样例输出 359316 数据规模和约定 对于1

lintcode 中等题:Evaluate Reverse Polish notation逆波兰表达式求值

题目 逆波兰表达式求值 在逆波兰表达法中,其有效的运算符号包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰计数表达. 样例 ["2", "1", "+", "3", "*"] -> ((2 + 1) * 3) -> 9 ["4", "13", "5", "/", "+"]

使用逆波兰式进行表达式求值

中缀表达式及后缀表达式图解中说明了使用逆波兰式进行表达式求值的方法,这里使用C++进行实现.实现和原理讲解有一点不同,需要进一步进行细化. 关于将中缀表达式转换成后后缀表达式的规则: 规则:从左到右遍历中缀表达式的每个数字和符号,若是数字就输出,即成为后缀表达式的一部分:若是符号,则判断其与栈顶符号的优先级,是右括号或优先级低于找顶符号(乘除优先加减)则栈顶元素依次出找并输出,并将当前符号进栈,一直到最终输出后缀表达式为止. 上面的规则转换成下面的执行规则: 1.遇到操作数:直接输出(添加到后缀

蓝桥杯-历届试题-公式求值

历届试题 公式求值 时间限制:1.0s   内存限制:256.0MB 问题描述 输入n, m, k,输出下面公式的值. 其中C_n^m是组合数,表示在n个人的集合中选出m个人组成一个集合的方案数.组合数的计算公式如下. 输入格式 输入的第一行包含一个整数n:第二行包含一个整数m,第三行包含一个整数k. 输出格式 计算上面公式的值,由于答案非常大,请输出这个值除以999101的余数. 样例输入 313 样例输出 162 样例输入 201010 样例输出 359316 数据规模和约定 对于10%的数

NYOJ-301递推求值

递推求值 时间限制:1000 ms  |  内存限制:65535 KB 难度:4 描述 给你一个递推公式: f(x)=a*f(x-2)+b*f(x-1)+c 并给你f(1),f(2)的值,请求出f(n)的值,由于f(n)的值可能过大,求出f(n)对1000007取模后的值. 注意:-1对3取模后等于2 输入 第一行是一个整数T,表示测试数据的组数(T<=10000)随后每行有六个整数,分别表示f(1),f(2),a,b,c,n的值.其中0<=f(1),f(2)<100,-100<=

ffmpeg文档08-表达式计算/求值

8 表达式计算/求值 在计算表达式时,ffmpeg通过libavutil/eval.h接口调用内部计算器进行计算. 表达式可以包含一元运算符.运算符.常数和函数 两个表达式expr1和expr2可以组合起来成为"expr1;expr2" ,两个表达式都会被计算,但是新表达式(组合起来的)值实为表达式expr2的值. 表达式支持的二元运算符有:+,-,*,/,^ 一元运算符:+,- 以及下面的函数: abs(x) 返回x的绝对值. acos(x) 计算x反余弦 . asin(x) 计算x

NYOJ表达式求值

表达式求值 时间限制:3000 ms  |  内存限制:65535 KB 难度:4 描述 ACM队的mdd想做一个计算器,但是,他要做的不仅仅是一计算一个A+B的计算器,他想实现随便输入一个表达式都能求出它的值的计算器,现在请你帮助他来实现这个计算器吧. 比如输入:"1+2/4=",程序就输出1.50(结果保留两位小数) 输入 第一行输入一个整数n,共有n组测试数据(n<10). 每组测试数据只有一行,是一个长度不超过1000的字符串,表示这个运算式,每个运算式都是以"