【刷题笔记】第七天

文章目录

    • [924. 尽量减少恶意软件的传播](https://leetcode.cn/problems/minimize-malware-spread/)
      • 方法一,并查集
      • 方法二,dfs
  • [GCD and LCM ](https://vjudge.net.cn/problem/HDU-4497#author=KING_LRL)

924. 尽量减少恶意软件的传播

如果移除一个感染节点可以避免连通图内节点的感染,那么该节点可能是最终的答案

我们要找避免连通图内节点感染的最大值,也就是求最大的含感染节点的连通图(连通图内只能有一个感染节点

方法一,并查集

首先我们构建连通图,并统计连通图内的节点个数

然后求最大的含感染节点的连通图

看到连通图,就想到并查集

class Solution {
    int n;
    int[] p;
    int[] size; // 记录集合内的元素个数
    public int find(int i) {
        if (i != p[i]) {
            p[i] = find(p[i]);
        }
        return p[i];
    }
    public void union(int a, int b) {
        int aFather = find(a);
        int bFather = find(b);
        if (aFather != bFather) {
            p[bFather] = aFather;
            size[aFather] += size[bFather];
        }
    }
    public int minMalwareSpread(int[][] graph, int[] initial) {
        n = graph.length;
        p = new int[n];
        size = new int[n];
        for (int i = 0; i < n; ++i) {
            p[i] = i;
            size[i] = 1;
        }

        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (graph[i][j] == 1) {
                    union(i, j);
                }
            }
        }

        Arrays.sort(initial);
        // 维护感染节点所在的集合
        Map<Integer, ArrayList<Integer>> map = new HashMap<>(); // key:感染节点的代表节点,value:代表节点所在集合的感染情况(哪些节点已经感染了)
        for (int x : initial) {
            int xFather = find(x);
            if (!map.containsKey(xFather)) {
                map.put(xFather, new ArrayList<>());
            }
            ArrayList<Integer> list = map.get(xFather);
            list.add(x);
        }

        int cnt = 0; // 避免感染节点的最大值
        int ans = n; // 要移除的索引
        for (Integer key : map.keySet()) {
            ArrayList<Integer> value = map.get(key);
            if (value.size() > 1) {
                // 如果集合内的感染节点数超过1,那么移除任意哪个节点,都不能避免该集合内节点感染
                continue;
            }
            // value.size()肯定为1

            int t = value.get(0); // value中索引最小的感染节点
            int tFather = find(t);
            if (size[tFather] > cnt) {
                cnt = size[tFather];
                ans = t;
            } else if (size[tFather] == cnt && t < ans) {
                // 索引更小
                ans = t;
            }
        }
        // ans = n,表示没有找到最大的含感染节点的连通图,也就是说移除任何一个感染节点,最终的感染节点数是一样的
        return ans == n ? initial[0] : ans;
    }
}

方法二,dfs

求最大的连通块,dfs当然也能做

需要注意的是我们要求的连通块是只含有一个感染节点的连通块。

那么如何标记我们搜索的连通块是想要的连通块呢?
可以通过设置节点状态来判断,
一个感染节点也没找到,状态为-1
找到了第一个感染节点,状态为x (感染节点的编号)
又找到了感染节点,状态为-2

所以在搜索完一个连通块后,判断状态是否大于等于0,只有大于等于0的连通块才是我们想要的连通块。

class Solution {
    int n;
    boolean[] vis;
    boolean[] isInitial; // 判断是否是感染节点

    int nodeState = -1; // -1标识初始状态,x(大于等于0)找到一个感染节点,-2找到两个感染节点
    int size; // 计算连通块内的节点个数

    public void dfs(int x, int[][] graph) {
        vis[x] = true;
        size++;
        if (isInitial[x]) {
            // x是感染节点
            if (nodeState == -1) {
                // 找到了第一个感染节点
                nodeState = x;
            } else {
                nodeState = -2;
            }
        }
        for (int y = 0; y < graph[x].length; ++y) {
            if (vis[y]) continue;
            if (graph[x][y] == 1) {
                dfs(y, graph);
            }
        }
    }
    public int minMalwareSpread(int[][] graph, int[] initial) {
        n = graph.length;
        vis = new boolean[n];
        isInitial = new boolean[n];
        for (int i : initial) {
            isInitial[i] = true;
        }
        int maxSize = 0;
        int ans = n;
        Arrays.sort(initial);
        for (int i : initial) {
            if (vis[i]) continue;
            nodeState = -1;
            size = 0;
            dfs(i, graph);
            if (nodeState >= 0) {
                if (size > maxSize) {
                    maxSize = size;
                    ans = i;
                } else if (size == maxSize && i < ans) {
                    ans = i;
                }
            }
        }
        return ans == n ? initial[0] : ans;
    }
}

GCD and LCM

最大公因数、最小公倍数的性质:

假设gcd(x, y) = G,lcm(x, y) = L
1. L % G == 0
2. L / G = (x / G) * (y / G)
3. gcd(kx, ky) = k gcd(x, y) = kG,所以gcd(x/G, y/G) = 1
lcm(x/G, y/G) = L/G
4. 两个互素的数的最小公倍数等于两者乘积
5. gcd(x, y) * lcm(x, y) = x y

image-20240416213542708

对于此题x, y, z,假设gcd(x, y, z) = G, lcm(x, y, z) = L
我们令x’ = x/ G, y’= y/G, z’ = z /G,所以gcd(x’, y’, z’) = 1, lcm(x’, y’, z’) = L / G
所以我们将原问题转化为,(x,y,z)的最大公约数为1,最小公倍数为L/G的个数

令L’ = L / G
我们对L‘ 进行素因子分解,可得 L ′ = x 1 p 1 x 2 p 2 . . . x m p m ,其中 x 1 , x 2 , . . . , x m 都是素数 L'=x_1^{p_1}x_2^{p_2}... x_m^{p_m},其中x_1,x_2, ..., x_m都是素数 L=x1p1x2p2...xmpm,其中x1,x2,...,xm都是素数,这里默认使用了一个结论(任何数都可以分解为若干个素数的乘积),然后对x’,y‘,z’分解可得:
x ′ = x 1 a 1 x 2 a 2 . . . x m a m x'=x_1^{a_1}x_2^{a_2}... x_m^{a_m} x=x1a1x2a2...xmam
y ′ = x 1 b 1 x 2 b 2 . . . x m b m y'=x_1^{b_1}x_2^{b_2}... x_m^{b_m} y=x1b1x2b2...xmbm
z ′ = x 1 c 1 x 2 c 2 . . . x m c m z'=x_1^{c_1}x_2^{c_2}... x_m^{c_m} z=x1c1x2c2...xmcm

先看分解式的第一项 x 1 ? 1 x_1^{?_1} x1?1
由于gcd(x’, y’, z’) = 1,所以 a 1 , b 1 , c 1 a_1, b_1,c_1 a1,b1,c1中至少有一个是0,(假设 a 1 , b 1 , c 1 a_1, b_1,c_1 a1,b1,c1都不为0,那么最大公约数肯定不为1,因为他们都有 x 1 x_1 x1这个因子)
a 1 , b 1 , c 1 a_1, b_1,c_1 a1,b1,c1中至少有一个是 p 1 p_1 p1(因为他们的最小公倍数是L‘,如果 a 1 , b 1 , c 1 a_1, b_1,c_1 a1,b1,c1都不是 p 1 p_1 p1,那么他们的乘积也就是公倍数(不是最小公倍数,因为xyz不一定互质)的分解不存在 x 1 p 1 x_1^{p_1} x1p1这一项)
所以 a 1 , b 1 , c 1 a_1, b_1,c_1 a1,b1,c1至少一个是0,至少一个是 p 1 p_1 p1 ,情况如下:

  • 1个0, 2个p1, (0, p1, p1) , (p1, 0, p1), (p1, p1, 0) ,3种
  • 2个0 , 1个p1,(0, 0, p1), (p1, 0, 0), (0, p1, 0), 3种
  • 1个0, 1个p1,1~p1-1,(0, p1, 1~p1-1), … A 3 2 ( p 1 − 1 ) = 6 ( p 1 − 1 ) A^2_3(p_1 - 1) = 6(p_1-1) A32(p11)=6(p11)

所以总共有 6 p 1 种情况 6p_1种情况 6p1种情况,这是第一项的情况数,还有第二项,第三项…
根据乘法定理,总情况数= 6 p 1 ∗ 6 p 2 . . . ∗ 6 p m 6p_1*6p_2...*6p_m 6p16p2...6pm

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstring>
#include<algorithm>

using namespace std;
int main() {

	int t;
	scanf("%d", &t);
	while (t--) {
		int g, l;
		scanf("%d%d", &g, &l);
		if (l % g != 0) {
			printf("0\n");
			continue;
		}
		l = l / g;
		int x = 2; // 对l进行分解, l = 2^p1 + 3^p2 + ..
		int ans = 1;
		while (l > 1) {
			int cnt = 0; // 计算p1, p2..
			while (l % x == 0) {
				l = l / x;
				cnt++;
			}
			if (cnt > 0) {
				ans *= 6 * cnt;
			}
			
			x++;
		}
		printf("%d\n", ans);
	}

	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/550548.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

电机控制器电路板布局布线参考指导(五)

电机控制器电路板布局布线参考指导&#xff08;五&#xff09;大容量电容和旁路电容的放置 1.大容量电容的放置2.电荷泵电容器3.旁路电容/去耦电容的放置3.1 靠近电源3.2 靠近功率器件3.3 靠近开关电流源3.4 靠近电流感测放大器3.5 靠近稳压器 tips&#xff1a;资料主要来自网络…

环境搭建创建项目_使用DevEco开发工具进行开发_创建项目_认识项目结构---HarmonyOS4.0+鸿蒙NEXT工作笔记001

首先去下载DevEco Studio然后再去安装就可以了 安装下一步下一步非常简单 首先去安装nodejs,可以看到,有两个安装方法,左边是自己安装的制定文件夹就可以了,然后 右边是使用鸿蒙自带的,我们选择第二个 然后我们看这个ohpm其实就跟npm是一个意思,用来管理鸿蒙的包的. 这里我们…

apache配置ssl证书

SSL证书&#xff0c;即安全套接层证书&#xff0c;是一种数字证书&#xff0c;它通过在客户端浏览器和Web服务器之间建立一条加密通道&#xff0c;保证了双方传输信息的安全性。当用户访问一个使用SSL证书保护的网站时&#xff0c;浏览器会显示一个锁形图标&#xff0c;表示连接…

FILE类与IO流

目录 File类的实例化与常用方法 File类的理解 文件路径的表示方式&#xff1a; API的使用 IO流概述与流的分类 I/O流中的是Input/Output的缩写 IO流的分类&#xff08;不同角度&#xff09; Java程序中的IO流涉及40多个&#xff0c;但实际上都是由4个抽象类衍生出来的。 F…

零代码编程:用kimichat将mp4视频批量转为mp3音频

一个文件夹里面有多个子文件夹&#xff0c;里面的视频需要转成为mp3音频格式。可以在kimichat中键入提示词&#xff1a; 你是一个Python编程专家&#xff0c;要完成一个Python脚本的编写任务&#xff0c;具体步骤如下&#xff1a; 打开文件夹&#xff1a;D:\CHATGPT For TikT…

Docker Container (容器) 常见命令

Docker 容器的生命周期 什么是容器&#xff1f; 通俗地讲&#xff0c;容器是镜像的运行实体。镜像是静态的只读文件&#xff0c;而容器带有运行时需要的可写文件层&#xff0c;并且容器中的进程属于运行状态。即容器运行着真正的应用进程。容 器有初建、运行、停止、暂停和删除…

HTTP协议安全传输教程

HTTP协议有多个版本&#xff0c;包括但不限于HTTP/0.9、HTTP/1.0、HTTP/1.1、HTTP/2和HTTP/3。这些版本各自具有不同的特点和改进&#xff0c;以适应网络技术的发展和满足不同的需求。例如&#xff0c;HTTP/1.0使用文本格式传输数据&#xff0c;简单易用且兼容性好&#xff0c;…

安装指定版本的ant-design-vue和指定版本的@ant-design/icons-vue 图标组件包

前言&#xff1a; 最近在完成公司的项目时&#xff0c;为了兼容其他的版本&#xff0c;需要安装指定版本的ant-design-vue和ant-design/icons-vue 图标组件包&#xff0c;安装成功之后&#xff0c;分享如下&#xff1a; 安装命令&#xff1a; ant-design-vue&#xff1a; 不…

深入剖析跨境电商平台风控机制,探索测评安全与稳定的秘诀

在跨境电商测评市场鱼龙混杂的当下&#xff0c;测评过程中可能隐藏的陷阱保持高度警觉。多年的测评经验告诉我们&#xff0c;选择一个适合的测评系统对于项目的成功至关重要。近年来&#xff0c;测评技术如雨后春笋般涌现&#xff0c;市场上涌现出众多测评系统&#xff0c;覆盖…

Spring Boot 处理过滤器(filter )中抛出的异常

前言&#xff1a; 在改造老项目登录功能的时候&#xff0c;使用了过滤器对 token 进行有效性验证&#xff0c;验证通过继续进行业务请求&#xff0c;验证不通过则抛出校验异常。 过程&#xff1a; 技术方案拟定后&#xff0c;就着手开始改造&#xff0c;一切都很顺畅&#x…

Linux用户及用户组管理命令

Linux操作系统是一种基于UNIX的多用户、多任务的操作系统。在Linux系统中&#xff0c;用户和用户组的管理是非常重要的&#xff0c;因为它关系到系统安全和多用户环境下的资源共享。本文将详细介绍Linux中用户和用户组管理的相关命令&#xff0c;帮助用户更好地理解和管理Linux…

SpringBoot整合minio服务

这里我选用的是JDK1.8 SpringBoot2.3.12.RELEASE 一、导入依赖 <dependency><groupId>io.minio</groupId><artifactId>minio</artifactId><version>8.2.2</version> </dependency> 二、导入工具类 注意&#xff1a;需要在…

DP4 最小花费爬楼梯

原题链接&#xff1a;最小花费爬楼梯_牛客题霸_牛客网 目录 1. 题目描述 2. 思路分析 3. 代码实现 1. 题目描述 2. 思路分析 dp。 开一个dp数组和a数组。dp[i]表示在当前这一格所需要的费用&#xff0c;a数组其实就是题目中的cost数组。 因为最后要求到顶楼的最低费用&a…

Redis: java客户端

文章目录 一、Redis的Java客户端1、Jedis&#xff08;1&#xff09;Jedis操作Redis&#xff08;2&#xff09;Jedis连接池 2、lettuce3、Redisson4、SpringDataRedis客户端&#xff08;1&#xff09;介绍&#xff08;2&#xff09;序列化&#xff08;3&#xff09;StringRedisT…

中国人工智能产业年会智能交通与自动驾驶专题全景扫描

中国人工智能产业年会&#xff08;CAIIAC&#xff09;是中国人工智能技术发展和应用的重要展示平台&#xff0c;不仅关注创新&#xff0c;还涵盖了市场和监管方面的内容&#xff0c;对于促进人工智能领域的发展起到了重要作用。年会汇集了来自学术界、工业界和政府的专家&#…

Python数据可视化:无向网络图

【小白从小学Python、C、Java】 【计算机等考500强证书考研】 【Python-数据分析】 Python数据可视化&#xff1a; 无向网络图 [太阳]选择题 关于以下代码输出结果的说法中正确的是? import networkx as nx import matplotlib.pyplot as plt a [(A, B), (B, C), (B, D)] …

基于小程序实现的4s店管理系统

作者主页&#xff1a;Java码库 主营内容&#xff1a;SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、小程序、安卓app等设计与开发。 收藏点赞不迷路 关注作者有好处 文末获取源码 技术选型 【后端】&#xff1a;Java 【框架】&#xff1a;ssm 【…

字体反爬积累知识

目录 一、什么是字体反扒 二、Unicode编码 三、利用font包获取映射关系 一、什么是字体反扒 字体反爬是一种常见的反爬虫技术&#xff0c;它通过将网页中的文本内容转换为特殊的字体格式来防止爬虫程序直接获取和解析文本信息。字体反爬的原理是将常规的字符映射到特殊的字…

MyBatisPlus自定义SQL

✅作者简介:大家好,我是Leo,热爱Java后端开发者,一个想要与大家共同进步的男人😉😉🍎个人主页:Leo的博客💞当前专栏: 循序渐进学SpringBoot ✨特色专栏: MySQL学习 🥭本文内容:MyBatisPlus自定义SQL 📚个人知识库: Leo知识库,欢迎大家访问 目录 1.前言☕…

ArcGIS三维景观分层显示

今天将向大家介绍的事在ArcGIS中如何创建多层三维显示。 地表为影像的 地表为地形晕渲的 在土壤分层、油气分层等都有着十分重要的应用。下面我们具体来看看实现过程 一、 准备数据及提取栅格范围 我们这次准备的数据是之前GIS100例-30讲的案例数据。《ArcGIS三维影像图剖面图…