当前位置: 首页 > news >正文

蓝桥杯第18489题——拔苗助长(质数+map)

问题描述

蓝桥村是蓝桥王国年年的模范村,这是因为他们村的稻田每年都是优美的。

对于一块稻田来说,如果其中任意两根不同的秧苗的高度乘积均为完全平方数,该稻田被称之为优美的稻田。

蓝桥王国的稻田验收日即将到来,但现在蓝桥村还有一块插了 𝑁 根秧苗的稻田不够优美,其中第 𝑖 根秧苗的高度为 ℎ𝑖。

作为蓝桥杯的村长,你可以发动技能拔苗助长:

  • 选择一个质数 x (2 ≤ x ≤ 10^6) ,同时将任意一株高度为 ℎ 的秧苗变为 ℎ×𝑥。

请问你最少需要发动多少次拔苗助长才可以将该稻田变得优美。

输入格式

第一行输入一个整数 𝑁 (1 ≤ 𝑁 ≤ 10^5) 表示稻田中秧苗的数量。

第二行输入 𝑁N 个整数 ℎ1,ℎ2,ℎ3,⋯,ℎ𝑁 (1 ≤ 𝐴𝑖 ≤ 10^6) 表示秧苗的高度。

输出格式

输出一个整数表示答案。

输入样例

5
1 2 3 4 5

输出样例

3

解题思路

题目说让每两个数相乘都是一个完全平方数,这里不难想到分解质因数,如果要满足这个要求,则需要任意两个数相乘,其所有质因数都是偶数个数。

对于任意质因数p,任意两个数相乘的结果中p的个数为偶数,则说明两个数中的p的个数要么都是奇数,要么都是偶数;反过来说,如果存在任意两个数a和b,假设a的质因数2的个数为1个,那么b的质因数2的个数如果是偶数,则a和b相乘的结果必不可能是完全平方数。

因此我们考虑对于每一个数x进行统计,计算其所有质因数出现的次数,对于某个质因数p,如果其对于某个x出现的次数为奇数,就记录一次;这样的目的是方便我们最终考虑是将每个数中的p都变成奇数个还是偶数个。

举一个具象化的例子,对于一个数列2 2 2 3:对质因数2来说,有三个x存在奇数个2;对质因数3来说,有一个x存在奇数个3。上述情况中,我们应该选择将所有x中质因数2的个数补齐到奇数个,这样只需要操作4 - 3 = 1次;而对于质因数3,我们应该选择补齐到偶数个,这样只需要操作1次。

所以可以考虑到,对于每个质因数p,其在每个x中出现奇数次的次数num,对答案的贡献是min(num, n - num)。

为了记录每一个x的每一个质因数的个数,我们可以使用Map数据结构,同时可以使用埃氏筛加快这个过程,我们筛选出log(N)以内所有质数逐一测试,如果在试除计算的最后没有变成1,则其本身就是一个质数,即自己的一个质因数。

import java.util.*;public class Main {static final int inf = (int) 1e9;static final int N = (int) Math.sqrt(1e6 + 1);static boolean[] prime;static ArrayList<Integer> primeList;public static void main(String[] args) {e_sieve();System.out.println(primeList);Scanner sc = new Scanner(System.in);int n = sc.nextInt();Map<Integer, Integer> mapAll = new HashMap<Integer, Integer>();for (int i = 0; i < n; i++) {int temp = sc.nextInt();Map<Integer, Integer> map = new HashMap<Integer, Integer>();for (int e : primeList) {while (temp % e == 0) {temp /= e;map.put(e, map.getOrDefault(e, 0) + 1);}if (temp == 1) {break;}}if (temp != 1) {map.put(temp, 1);}for (java.util.Map.Entry<Integer, Integer> e : map.entrySet()) {if (e.getValue() % 2 == 1) {mapAll.put(e.getKey(), mapAll.getOrDefault(e.getKey(), 0) + 1);}}}System.out.println(mapAll);long ans = 0;for (int e : mapAll.values()) {ans += Math.min(e, n - e);}System.out.print(ans);}static void e_sieve() {primeList = new ArrayList<Integer>();prime = new boolean[N];Arrays.fill(prime, true);prime[0] = false; prime[1] = false;for (int i = 2; i < N; i++) {if (prime[i]) {primeList.add(i);for (long j = 1L * i * i; j < N; j += i) {prime[(int)j] = false;}}}}
}

相关文章:

  • 修改元组元素
  • NIO的ByteBuffer和Netty的ByteBuf的性能
  • 服务器数据恢复—服务器raid常见故障表现原因解决方案
  • 测试基础06:软件产品的运行环境dev、sit、test、fat、uat、pre、pro
  • Eclipse下载安装教程(包含JDK安装)【保姆级教学】【2024.4已更新】
  • SpringSession原理简析
  • 【软考中级 软件设计师】计算机网络和安全
  • 软件测试外包公司测试流程分享,与企业内部测试人员的区别有哪些?
  • 【Torch学习笔记】
  • Python中的yield关键字,掌握生成器的精髓
  • linux下宝塔负载100%解决方法
  • 存储+调优:存储-IP-SAN
  • NumPy 随机数据分布与 Seaborn 可视化详解
  • 请叙述Vue 中使用了哪些设计模式
  • 安装和配置 FRP (Fast Reverse Proxy)
  • @angular/forms 源码解析之双向绑定
  • [数据结构]链表的实现在PHP中
  • Bytom交易说明(账户管理模式)
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • CSS选择器——伪元素选择器之处理父元素高度及外边距溢出
  • express如何解决request entity too large问题
  • Java知识点总结(JavaIO-打印流)
  • Just for fun——迅速写完快速排序
  • Linux下的乱码问题
  • Octave 入门
  • SAP云平台运行环境Cloud Foundry和Neo的区别
  • vue中实现单选
  • 不用申请服务号就可以开发微信支付/支付宝/QQ钱包支付!附:直接可用的代码+demo...
  • 前端面试总结(at, md)
  • 前端性能优化--懒加载和预加载
  • 我感觉这是史上最牛的防sql注入方法类
  • 我与Jetbrains的这些年
  • 小程序、APP Store 需要的 SSL 证书是个什么东西?
  • 一个普通的 5 年iOS开发者的自我总结,以及5年开发经历和感想!
  • ​​​​​​​sokit v1.3抓手机应用socket数据包: Socket是传输控制层协议,WebSocket是应用层协议。
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​Linux Ubuntu环境下使用docker构建spark运行环境(超级详细)
  • ## 1.3.Git命令
  • #Linux(Source Insight安装及工程建立)
  • (1)无线电失控保护(二)
  • (2024,Flag-DiT,文本引导的多模态生成,SR,统一的标记化,RoPE、RMSNorm 和流匹配)Lumina-T2X
  • (CPU/GPU)粒子继承贴图颜色发射
  • (C语言)求出1,2,5三个数不同个数组合为100的组合个数
  • (黑客游戏)HackTheGame1.21 过关攻略
  • (力扣)1314.矩阵区域和
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (免费领源码)Python#MySQL图书馆管理系统071718-计算机毕业设计项目选题推荐
  • (三) diretfbrc详解
  • (四)c52学习之旅-流水LED灯
  • (新)网络工程师考点串讲与真题详解
  • (最优化理论与方法)第二章最优化所需基础知识-第三节:重要凸集举例
  • ***测试-HTTP方法
  • .net core Swagger 过滤部分Api
  • .NET Core 网络数据采集 -- 使用AngleSharp做html解析
  • .Net Redis的秒杀Dome和异步执行