7-4 区间水仙花数 Python程序设计-MJU实验四(编程入门•多代码实现•测试均通过)

给定一个包含 n 个元素的数组 a 和 q 个查询(用 l 和 r 表示一个范围),输出区间 l,r 中水仙花数的个数。在数论中,水仙花数(Narcissistic number),也被称为超完全数字不变数、自恋数或阿姆斯特朗数(Armstrong number),用来描述一个 n 位非负整数,其各位数字的 n 次方和等于该数本身,即 (d1​d2​⋯dn​)=d1n​+d2n​+⋯+dnn​。

输入格式:

第一行输入两个整数 n(1≤n≤105)、q(1≤q≤105);

第二行输出 n 个空格隔开的非负整数 ai​(0≤ai​≤109);

接下来 q 行,每一行两个整数 li​,ri​(1≤li​≤ri​≤n)。

输出格式:

输出 q 行,每一行输出区间 [li​,ri​] 水仙花数的个数。

输入样例:

复制代码
5 2
1 11 2 22 3
1 3
4 5 

输出样例:

复制代码
2
1

样例解释

区间 [1,3] 有两个水仙花数 1 和 2;

区间 [4,5] 有一个水仙花数 3。

python 复制代码
import sys

def main():
    # 快速读取所有输入(因为数据量很大,用sys.read更快)
    data = list(map(int, sys.stdin.read().split()))
    ptr = 0  # 指针,用来逐个取数据
    
    # 第一步:读n(数组长度)和q(查询次数)
    n = data[ptr]
    q = data[ptr+1]
    ptr += 2
    
    # 第二步:读数组a的n个元素
    a = data[ptr:ptr+n]
    ptr += n
    
    # 预处理:提前算好0-9的1~10次方(因为a_i最大是1e9,最多10位)
    # pre_pow[d][k] = 数字d的k次方
    pre_pow = [[0]*(11) for _ in range(10)]  # d是0-9,k是1-10
    for d in range(10):
        for k in range(1, 11):
            pre_pow[d][k] = d ** k
    
    # 第三步:标记每个元素是否是水仙花数(生成is_narc数组)
    is_narc = [0] * n  # 初始都是0(不是)
    for i in range(n):
        x = a[i]
        if x == 0:
            # 0是1位,0^1=0 → 是水仙花数
            is_narc[i] = 1
            continue
        # 计算x的位数k
        s = str(x)
        k = len(s)
        total = 0
        temp = x
        # 计算各位数字的k次方和
        while temp > 0:
            digit = temp % 10  # 取最后一位数字
            total += pre_pow[digit][k]  # 用预处理的次方,更快
            temp = temp // 10  # 去掉最后一位
        # 判断和是否等于原数
        if total == x:
            is_narc[i] = 1  # 是水仙花数,标记为1
    
    # 第四步:计算前缀和数组(方便快速查询区间和)
    # prefix[0] = 0,prefix[1] = is_narc[0],prefix[2] = is_narc[0]+is_narc[1]...
    prefix = [0] * (n + 1)
    for i in range(n):
        prefix[i+1] = prefix[i] + is_narc[i]
    
    # 第五步:处理每个查询
    output = []
    for _ in range(q):
        l = data[ptr]
        r = data[ptr+1]
        ptr += 2
        # 区间[l,r]的水仙花数个数 = 前缀和[r] - 前缀和[l-1]
        cnt = prefix[r] - prefix[l-1]
        output.append(str(cnt))
    
    # 输出所有结果(批量输出更快)
    print('\n'.join(output))

if __name__ == "__main__":
    main()
相关推荐
万行3 小时前
机器学习&第五章生成式生成器
人工智能·python·算法·机器学习
罗湖老棍子3 小时前
【模板】并查集(洛谷P3367)
算法·图论·并查集
_OP_CHEN3 小时前
【算法基础篇】(四十五)裴蜀定理与扩展欧几里得算法:从不定方程到数论万能钥匙
算法·蓝桥杯·数论·算法竞赛·裴蜀定理·扩展欧几里得算法·acm/icpc
shangjian0074 小时前
AI大模型-机器学习-算法-线性回归
人工智能·算法·机器学习
go_bai4 小时前
Linux-网络基础
linux·开发语言·网络·笔记·学习方法·笔记总结
我命由我123454 小时前
Photoshop - Photoshop 工具栏(58)锐化工具
学习·ui·职场和发展·求职招聘·职场发展·学习方法·photoshop
2301_800256114 小时前
B+树:数据库的基石 R树:空间数据的索引专家 四叉树:空间划分的网格大师
数据结构·数据库·b树·机器学习·postgresql·r-tree
mjhcsp4 小时前
C++ KMP 算法:原理、实现与应用全解析
java·c++·算法·kmp
lizhongxuan4 小时前
Manus: 上下文工程的最佳实践
算法·架构
码农幻想梦4 小时前
第九章 高级数据结构
数据结构