数论——因子组合

简介: 数论——因子组合


题目

到 X 星球旅行的游客都被发给一个整数,作为游客编号。X 星的国王有个怪癖,他只喜欢数字 3,5 和 7。

国王规定,游客的编号如果只含有因子:3,5,7 就可以获得一份奖品。

我们来看前 10 个幸运数字是:

3 5 7 9 15 21 25 27 35 45 因而第 11 个幸运数字是: 49

小明领到了一个幸运数字 59084709587505,他去领奖的时候,人家要求他准确地说出这是第几个幸运数字,否则领不到奖品。

请你帮小明计算一下,59084709587505 是第几个幸运数字。


常规思路or错误思路

首先来分析一下这道题:初次接触此类题的时候,我们通常会想到,先写一个方法——判断某个数的因子是否只含有3,5,7;于是乎,我们写了一个方法,这个方法也确实能够做出准确的判断,而在这个方法中,你或许还会用到一些集合,比如HashSet等…然后输入49,得出是第11个数。


int类型代码如下(Java):

import java.util.HashSet;
public class Main{
    static HashSet<Integer> hashSet = new HashSet<>();
    public static void main(String[] args) {
//        long num = 59084709587505L;
        int num = 49;
        int count = 2;
        while (3 * count < num) {
            hashSet.add(3 * count);
            count++;
        }
        count = 2;
        while (5 * count < num) {
            hashSet.add(5 * count);
            count++;
        }
        count = 2;
        while (7 * count < num) {
            hashSet.add(7 * count);
            count++;
        }
        count = 0;
        for (int i = 2; i <= num; i++) {
            if (judge(i))
                count++;
        }
        System.out.println(count);
    }
    private static boolean judge(int num) {
        boolean flag = num % 3 == 0 || num % 5 == 0 || num % 7 == 0;
        for (int i = 2; i < num; i++) {
            if (i != 3 && i != 5 && i != 7 && !hashSet.contains(i))
                if (num % i == 0) {
                    flag = false;
                    break;
                }
        }
        return flag;
    }
}

BigInteger类型代码如下(Java):

import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashSet;
public class demo04_BigInteger {
    public static void main(String[] args) {
        BigInteger num = new BigInteger("49");
        int count = 0;
        int i = 2;
        BigInteger temp = new BigInteger(String.valueOf(i));
        while (true) {
            if (temp.compareTo(num) <= 0) {
                if (judge(temp)) {
                    count++;
                    System.out.print(temp+" ");
                }
                temp = new BigInteger(String.valueOf(++i));
            } else break;
        }
        System.out.println(count);
    }
    private static boolean judge2(BigInteger i) {
        if (i.compareTo(BigInteger.valueOf(3)) == 0 || i.compareTo(BigInteger.valueOf(5)) == 0 || i.compareTo(BigInteger.valueOf(7)) == 0)
            return true;
        while (i.mod(BigInteger.valueOf(3)).compareTo(BigInteger.valueOf(0)) == 0)
            i = i.divide(BigInteger.valueOf(3));
        while (i.mod(BigInteger.valueOf(5)).compareTo(BigInteger.valueOf(0)) == 0)
            i = i.divide(BigInteger.valueOf(5));
        while (i.mod(BigInteger.valueOf(7)).compareTo(BigInteger.valueOf(0)) == 0)
            i = i.divide(BigInteger.valueOf(7));
        return i.compareTo(BigInteger.valueOf(1)) == 0;
    }
    private static boolean judge(BigInteger num) {
        boolean flag = Integer.parseInt(num.mod(BigInteger.valueOf(3)).toString()) == 0 || Integer.parseInt(num.mod(BigInteger.valueOf(5)).toString()) == 0 || Integer.parseInt(num.mod(BigInteger.valueOf(7)).toString()) == 0;
        BigInteger temp = new BigInteger(String.valueOf(2));
        while (true) {
            if (temp.compareTo(num) < 0) {
                if (!judge2(temp))
                    if (Integer.parseInt(num.mod(temp).toString()) == 0) {
                        flag = false;
                        break;
                    }
                temp = temp.add(BigInteger.valueOf(1));
            } else
                break;
        }
        return flag;
    }
}

就在我以为大功告成的时候,将数字改为59084709587505(用long存储 ),发现hashset爆栈了或者是一直跑不出来——超时了!这题这么有难吗?怎么办呢?接着往下看!


正确思路(一)

这里说一下我后来想到的办法,可能还能做优化,但是目前已经是能用的了,如有更好的方法,请在评论区留言指点,不胜感激!


其实这类题和快速幂等数论思想一样,从已知条件入手,不考虑无关内容,从而优化循环,降低复杂度


解题思路:

由于因子只含有3,5,7,所以满足该条件的数一定是由 : 3的某次方 * 5的某次方 * 7的某次方 构成,而这样组成的数相对于全部的数,它们只占少部分,则可以直接暴力求解!

定义三个变量,三个变量都从0开始,因为一个数的0次方法等于1,相乘不会影响结果,但需要注意的是,要排除掉1这个数字,并且给定的那个数是需要取到的,所以我们列出公式:

for (int x = 0; Math.pow(3, x) <= num; x++)

for (int y = 0; Math.pow(5, y) <= num; y++)

for (int z = 0; Math.pow(7, z) <= num; z++)

这样就能遍历出全部的“幸运数字”,然后加以判断,只要“幸运数字”是<=number的,就追加个数。

代码如下(Java):

public class Main {
    public static void main(String[] args) {
        long num = 59084709587505L;
        int count = 0;
        for (int x = 0; Math.pow(3, x) <= num; x++)
            for (int y = 0; Math.pow(5, y) <= num; y++)
                for (int z = 0; Math.pow(7, z) <= num; z++)
                    if (Math.pow(3, x) * Math.pow(5, y) * Math.pow(7, z) <= num)
                        count++;
        System.out.println(count - 1);
    }
}
相关文章
|
安全 关系型数据库 Linux
一文教你搭建个人网盘filerun,拥有私人文件服务器
一文教你搭建个人网盘filerun,拥有私人文件服务器
一文教你搭建个人网盘filerun,拥有私人文件服务器
|
应用服务中间件 Linux nginx
|
存储 监控 安全
Zabbix登录绕过漏洞复现(CVE-2022-23131)
最近在复现zabbix的漏洞(CVE-2022-23131),偶然间拿到了国外某公司zabbix服务器。Zabbix Sia Zabbix是拉脱维亚Zabbix SIA(Zabbix Sia)公司的一套开源的监控系统。该系统支持网络监控、服务器监控、云监控和应用监控等。Zabbix Frontend 存在安全漏洞,该漏洞源于在启用 SAML SSO 身份验证(非默认)的情况下,恶意行为者可以修改会话数据,因为存储在会话中的用户登录未经过验证。 未经身份验证的恶意攻击者可能会利用此问题来提升权限并获得对 Zabbix 前端的管理员访问权限。
2419 0
Zabbix登录绕过漏洞复现(CVE-2022-23131)
|
7月前
|
消息中间件 关系型数据库 Java
击穿分布式事务痛点:BASE 理论全解,从最终一致性到柔性事务落地全指南
本文深入解析分布式事务核心理论BASE(基本可用、软状态、最终一致性),对比ACID差异,详解五大最终一致性模型,并结合本地消息表、TCC、SAGA等四种柔性事务方案,提供可落地的代码实例与避坑指南,助你平衡一致性与可用性。
1072 1
|
8月前
|
Web App开发 编解码 Java
WebRTC 核心原理拆解与企业级 RTC SDK 落地实践
WebRTC作为实时音视频通信的核心技术,其完整技术栈包含音视频采集、编码、传输、解码和渲染等模块。文章深入解析了WebRTC的底层架构,重点介绍了NAT穿透(ICE/STUN/TURN)、音视频编解码(VP8/OPUS)和媒体传输(RTP/SRTP)等关键技术。通过Java实现的RTC SDK示例,展示了如何构建企业级解决方案,包括环境配置、核心代码实现和功能验证。最后提出了性能优化(抗丢包、延迟控制)、稳定性(断线重连、TURN容灾)和安全性(SRTP加密、信令鉴权)等关键策略,并针对NAT穿透失败、音视频不同步等常见问题提供了解决方案。
829 3
|
6月前
|
人工智能 JSON Oracle
Oracle中各个c版本介绍
Oracle数据库“c”系列(Cloud)始于2013年12c,标志多租户架构革命。当前生产首选19c(长期稳定),学习与AI应用推荐23ai(原23c),支持向量搜索与JSON关系二元性;21c为短期创新版,12c/18c已停更。云原生演进清晰,稳中求新。(239字)
1819 4
|
7月前
|
人工智能 缓存 文字识别
OpenClaw进阶指南:阿里云/本地部署+API配置+多模态融合+跨平台联动实战手册
2026年,AI技术的核心进化方向已从单一文本交互转向多模态融合,OpenClaw(曾用名Clawdbot)凭借开放的插件生态与灵活的部署架构,率先实现“文本、图像、语音、视频”的全维度交互支持。无论是通过语音下达复杂任务、让AI分析视频核心信息,还是上传图像实现智能识别,OpenClaw都能打破信息形态的边界,成为连接虚拟与现实的高效桥梁。
1226 16
|
缓存 Kubernetes Docker
GitLab Runner 全面解析:Kubernetes 环境下的应用
GitLab Runner 是 GitLab CI/CD 的核心组件,负责执行由 `.gitlab-ci.yml` 定义的任务。它支持多种执行方式(如 Shell、Docker、Kubernetes),可在不同环境中运行作业。本文详细介绍了 GitLab Runner 的基本概念、功能特点及使用方法,重点探讨了流水线缓存(以 Python 项目为例)和构建镜像的应用,特别是在 Kubernetes 环境中的配置与优化。通过合理配置缓存和镜像构建,能够显著提升 CI/CD 流水线的效率和可靠性,助力开发团队实现持续集成与交付的目标。
Xmind2022最新版破解与激活教程,操作简单
Xmind 是一款 全功能 的思维导图和头脑风暴软件。像大脑的瑞士军刀一般,助你理清思路,捕捉创意。
4922 0

热门文章

最新文章