2525.根据规则将箱子分类/并查集/动态规划

2525. 根据规则将箱子分类 - 力扣(LeetCode)

给你四个整数 length ,width ,height 和 mass ,分别表示一个箱子的三个维度和质量,请你返回一个表示箱子 类别 的字符串。

  • 如果满足以下条件,那么箱子是 "Bulky" 的:
    • 箱子 至少有一个 维度大于等于 104 。
    • 或者箱子的 体积 大于等于 109 。
  • 如果箱子的质量大于等于 100 ,那么箱子是 "Heavy" 的。
  • 如果箱子同时是 "Bulky" 和 "Heavy" ,那么返回类别为 "Both" 。
  • 如果箱子既不是 "Bulky" ,也不是 "Heavy" ,那么返回类别为 "Neither" 。
  • 如果箱子是 "Bulky" 但不是 "Heavy" ,那么返回类别为 "Bulky" 。
  • 如果箱子是 "Heavy" 但不是 "Bulky" ,那么返回类别为 "Heavy" 。

注意,箱子的体积等于箱子的长度、宽度和高度的乘积。

示例 1:

输入:length = 1000, width = 35, height = 700, mass = 300
输出:"Heavy"
解释:
箱子没有任何维度大于等于 104 。
体积为 24500000 <= 109 。所以不能归类为 "Bulky" 。
但是质量 >= 100 ,所以箱子是 "Heavy" 的。
由于箱子不是 "Bulky" 但是是 "Heavy" ,所以我们返回 "Heavy" 。

示例 2:

输入:length = 200, width = 50, height = 800, mass = 50
输出:"Neither"
解释:
箱子没有任何维度大于等于 104 。
体积为 8 * 106 <= 109 。所以不能归类为 "Bulky" 。
质量小于 100 ,所以不能归类为 "Heavy" 。
由于不属于上述两者任何一类,所以我们返回 "Neither" 。

提示:

  • 1 <= length, width, height <= 105
  • 1 <= mass <= 103

思路

用数学公式,然后进行判断,返回值

完整代码

class Solution {public String categorizeBox(int length, int width, int height, int mass) {long maxd = Math.max(length, Math.max(width, height)), vol = 1L * length * width * height;boolean isBulky = maxd >= 10000 || vol >= 1000000000, isHeavy = mass >= 100;if (isBulky && isHeavy) {return "Both";} else if (isBulky) {return "Bulky";} else if (isHeavy) {return "Heavy";} else {return "Neither";}}
}

 题目来源:【模板】并查集 - 洛谷

就是将要合并的数做成一个集合,然后再查找;

其实我觉得并查集好像最关键的就是找根节点,只要跟根节点扯上关系就能证明属于一个集合;

所以首先我先做了一个查找根节点的函数

public static int find(int x,int p[])
{int x_root=x;while(p[x_root]!=-1)x_root = p[x_root];return x_root;}

 首先我会让所有数都指向自己,也就是我先都把他们的节点设为-1(因为题目中有说集合中的元素都是大于0的,就不用担心出现漏洞;然后就是用循环一步步往上找,知道找到根节点,然后返回根节点的值;

public static void op(int x,int y,int p[])
{int x_root = x;int y_root = y;int find(int x,int p[]);x_root = find(x,p);y_root = find(y,p);if(x_root != y_root)p[x_root] = y_root ;
}

然后我又做了一个合并的函数,就是把有关系的集合合并起来,也是利用的根节点,先找到我要合并的集合的根节点,然后合并;

class Text(){public static void main(Sting[]args)
{int m,n;int x,y,z,v;int find(int x,int p[]);scanf("%d %d",&m,&n);int p[m+1];for(int i=1;i<=m;i++)p[i]=-1;
}

然后在主函数中,将数据都输入,特别是将父节点数组全部初始化为-1。

  for(int i=0;i<n;i++){scanf("%d %d %d",&x,&y,&z);if(x==1)op(y,z,p);if(x==2){int y_root,z_root;y_root = find(y,p);z_root = find(z,p);if(y_root == z_root)printf("Y\n");elseprintf("N\n");}}return 0;
}

然后就是,判断是做集合还是找集合,如果是1就是做集合,如果是2就是找集合,然后按条件输出Y或者N;

 (最后交上去出来的结果也不是很好,发现时间有点超限,应该是数据类型不对,或者说我要用路径压缩)

改错:

我知道为什么时间超限了,因为我没有按照把小的树往大的树上面凑,而是随便凑,那么这样就会导致树的深度变大,也就是说时间会变长,那么我只需要在我将集合合并的函数上加上一组判断的语句;

public static void op(int x,int y,int p[],int rank[])
{int x_root = x;int y_root = y;int find(int x,int p[]);x_root = find(x,p);y_root = find(y,p);if(x_root != y_root){if(rank[x_root] > rank[y_root])p[y_root]=x_root;else if(rank[x_root] < rank[y_root])p[x_root] = y_root;else{p[x_root] = y_root;rank[y_root]++;}}
}

rank[]数组就是树的高度,首先判断树的高度,然后将小的树往大的树上面扣,这样找的时候就能有效节省时间复杂度;

 例题一(链接)

# 【模板】最长公共子序列

## 题目描述

给出 $1,2,\ldots,n$ 的两个排列 $P_1$ 和 $P_2$ ,求它们的最长公共子序列。

## 输入格式

第一行是一个数 $n$。

接下来两行,每行为 $n$ 个数,为自然数 $1,2,\ldots,n$ 的一个排列。

## 输出格式

一个数,即最长公共子序列的长度。

## 样例 #1

### 样例输入 #1

```

3 2 1 4 5
1 2 3 4 5
```

### 样例输出 #1

```
3
```

## 提示

- 对于 $50\%$ 的数据, $n \le 10^3$;
- 对于 $100\%$ 的数据, $n \le 10^5$。

思路

本来我用的是滚动数组来做,但是还是时间超限了,我猜测应该不能一组数据一组数据的更新,然后看题目中说是由相同的数字组成,那么就是说只是顺序不同,但元素是相同的,其实这个题就是LIS(参考文章),以一个串为模板串,然后判断另一个串在这个串里面的排列顺序;

代码

class Text{int inf = 100010l;public static int min(int x,int y)
{return x<y?x:y;
}public static void main(String[]args)
{Scanner sc = new Scanner(System.in);int n = sc.nextInt();int []p1 = new int[num];int []p2 = new int[num];int []dp = new int[num];int []map = new int[map];     //dp表示的是合乎题意的子串,map下标表示的是数值,而其对应的数字是该数值的位置;for(int i=1; i<=n; i++){p1[i] = sc.nextInt();dp[i]=inf;            //初始化map[p1[i]]=i;         //明确一个串里面数字的顺序,以便之后另一个串的数字在这个串里面找位置}for(int i=1; i<=n; i++)scanf("%d",&p2[i]);int len=0;               //找到的合乎题目意思的子串长度dp[0]=0;                 for(int i=1; i<=n; i++){int xx=0,r=len,mid;  if(map[p2[i]]>dp[len])  //如果说p2第i个数字在p1中的位置大于已有的子串的最后一个数字dp[++len]=map[p2[i]];  //那么就把这个数字加入子串中else{while(xx<r)   //二分查找(就是更加方便查找,节省时间){mid=(xx+r)/2;if(map[p2[i]]<dp[mid])r=mid;elsexx=mid+1;}dp[xx]=min(map[p2[i]],dp[xx]);}}printf("%d",len);  //len就是子串的长度}

例题二(编辑距离 - 洛谷)

# 编辑距离

## 题目描述

设 $A$ 和 $B$ 是两个字符串。我们要用最少的字符操作次数,将字符串 $A$ 转换为字符串 $B$。这里所说的字符操作共有三种:

1. 删除一个字符;
2. 插入一个字符;
3. 将一个字符改为另一个字符。

$A, B$ 均只包含小写字母。

## 输入格式

第一行为字符串 $A$;第二行为字符串 $B$;字符串 $A, B$ 的长度均小于 $2000$。

## 输出格式

只有一个正整数,为最少字符操作次数。

## 样例 #1

### 样例输入 #1

```
sfdqxbw
gfdgw
```

### 样例输出 #1

```
4
```

## 提示

对于 $100 \%$ 的数据,$1 \le |A|, |B| \le 2000$。

思路

首先知道有俩个字符串,那么可以建一个二维数组arr[ i ][ j ],分别用于俩个字符串的遍历;

然后根据题目可以知道,对于每一个字符,具有四种操作,删除,插入,替换,不变;那么就可以判断在不同情况下,该怎么更新arr里面的值;

当新遍历的俩个字符相等时,就不要增加步骤,那么此时这个点的步骤就和没新遍历的那俩个字符时相等,即 :

arr[ i ][ j ] = arr[ i - 1 ][ j - 1 ];

当不满足这个条件的时候,就考虑此时该进行什么操作,arr[ i ][ j - 1 ]表示的是增加一个字符的操作, arr[ i - 1 ][ j ]表示的是删除一个字符的操作,arr[ i - 1 ][ j - 1 ]表示替换;

代码

#include<stdio.h>
#include<string.h>
#define num 3010int min(int x,int y)
{return x<y?x:y;
}int main()
{char A[num],B[num];int arr[num][num];int a,b;scanf("%s%s",A,B);a=strlen(A);b=strlen(B);int c=a>b?a:b;for(int i=1;i<=c;i++){arr[i][0]=i;arr[0][i]=i;}for(int i=1; i<=a; i++)for(int j=1; j<=b; j++){if(A[i-1]==B[j-1]){arr[i][j]=arr[i-1][j-1];}elsearr[i][j]=min(min(arr[i-1][j],arr[i][j-1]),arr[i-1][j-1])+1;}printf("%d",arr[a][b]);return 0;
}

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【CSS】BFC 块级格式化上下文

1. 块级格式化上下文&#xff08;BFC&#xff09; 它是一块独立的渲染区域&#xff0c;规定该区域内&#xff0c;常规流块盒的布局。 先来说一下常规流块盒&#xff1a; 常规流块盒在水平方向上&#xff0c;必须盛满包含块常规流块盒在包含块的垂直方向上依次摆放常规流块盒…

面试官:说说webpack的构建流程?

一、运行流程 webpack 的运行流程是一个串行的过程&#xff0c;它的工作流程就是将各个插件串联起来 在运行过程中会广播事件&#xff0c;插件只需要监听它所关心的事件&#xff0c;就能加入到这条webpack机制中&#xff0c;去改变webpack的运作&#xff0c;使得整个系统扩展…

文心一言 VS 讯飞星火 VS chatgpt (118)-- 算法导论10.3 3题

三、用go语言&#xff0c;在ALLOCATE-OBJECT和 FREE-OBJECT过程的实现中&#xff0c;为什么不需要设置或重置对象的 prev 属性呢? 文心一言&#xff1a; 在 Go 语言中&#xff0c;ALLOCATE-OBJECT 和 FREE-OBJECT 过程的实现通常不需要显式地设置或重置对象的 prev 属性。这…

在Kubernetes(k8s)上部署整个SpringCloud微服务应用

视频教程地址&#xff1a;https://www.bilibili.com/video/BV1Xh4y1q7aW/ 文章目录 项目准备打成使用Docker打成镜像准备Docker仓库打包项目为Docker镜像 部署应用到k8s创建nfs挂载目录创建一些基本资源创建命名空间创建拉取镜像的secret创建java运行环境的profile 部署mysql创…

Docker数据管理、端口映射、容器互联

目录 一、Docker 的数据管理&#xff1a; 1&#xff0e;数据卷&#xff1a; 1.1 宿主机目录/var/www/html 挂载到容器中的/data1&#xff1a; 1.2 测试&#xff1a; 2&#xff0e;数据卷容器&#xff1a; 2.1 创建一个容器作为数据卷容器&#xff1a; 2.2 挂载a1容器中的数据卷…

局域网下多台windows电脑时间同步

windows时间同步 最近在项目中遇见了多台windows电脑的时间同步问题。在这个项目中&#xff0c;有五台电脑&#xff0c;五台电脑处于同一局域网下&#xff0c;其中有一台可以连接互联网&#xff08;A电脑&#xff09;。我需要将其他四台电脑&#xff08;B、C、D、E电脑&#xf…

微信native-v3版支付对接流程及demo

1.将p12证书转为pem证书&#xff0c;得到商户私钥 openssl pkcs12 -in apiclient_cert.p12 -out apiclient_cert.pem -nodes 密码是&#xff1a;商户id 2.将获取到的apiclient_cert.pem证书&#xff0c;复制出这一块内容&#xff0c;其他的不要 3.下载这个工具包 https://gi…

香港服务器在国内访问太慢怎么能提高?

​  一直以来&#xff0c;全球化业务需求的增长是跟随着蓬勃向上的互联网而发展的。有了网络&#xff0c;海外贸易就在鼠标的轻点中完成。而IDC市场中的香港服务器也因为免备案政策的特性&#xff0c;开始逐渐成为企业想要跨越地域壁垒而考虑的对象。但在使用过程中&#xff…

SpringAMQP

SpringAMQT RabbitMQ安装与部署RabbitMQ结构简单队列模型 SpringAMQP依赖引入配置RabbitMQ连接信息基本模型简单队列模型WorkQueue模型 发布订阅模型FanoutExchangeDirectExchangeTopicExchange 消息转换器 消息队列是实现异步通讯的一种方式&#xff0c;我们将从RabbitMQ为例开…

docker 部署mysql

Centos7为例 NAME"CentOS Linux" VERSION"7 (Core)" ID"centos" ID_LIKE"rhel fedora" VERSION_ID"7" PRETTY_NAME"CentOS Linux 7 (Core)" ANSI_COLOR"0;31" CPE_NAME"cpe:/o:centos:centos:7&qu…

Java File与IO流学习笔记

内存中存放的都是临时数据&#xff0c;但是在断电或者程序终止时都会丢失 而硬盘则可以长久存储数据&#xff0c;即使断电&#xff0c;程序终止&#xff0c;也不会丢失 File File是java.io.包下的类&#xff0c;File类的对象&#xff0c;用于代表当前操作系统的文件(可以是文…

C语言 ——宽字符

前言&#xff1a; 过去C语⾔并不适合⾮英语国家&#xff08;地区&#xff09;使⽤。 C语⾔最初假定字符都是单字节的。但是这些假定并不是在世界的任何地⽅都适⽤。 C语⾔字符默认是采⽤ASCII编码的&#xff0c;ASCII字符集采⽤的是单字节编码&#xff0c;且只使⽤了单字节中…