【java】嵌套矩形

本文介绍了一种算法,用于解决给定多个矩形时如何找出最多数量的矩形序列,使得序列中的每个矩形都能恰好嵌套在序列中的下一个矩形内。通过构建有向无环图并应用动态规划来寻找最长路径。

有n个矩形,每个矩形可以用两个整数a,b表示,分别表示它的长和宽。矩形X(a,b)可以嵌套在矩形Y(c,d)中当且仅当a<c,b<d或b<c,a<d。

例如:1,5可以嵌套在6,2内,但不能嵌套在3,4内。

给出n个矩形,选出尽量多的矩形排成一行,使得除了最后一个之外,每一个矩形都可以嵌套在下一个矩形内。

先输入矩形的数目n,紧接着输入n行,每行代表一个矩形,最后输出选出的矩形。

样例输入:

6
1,2
4,3
4,6
3,17
7,8
10,11

样例输出:

1,2
4,3
4,6
7,8
10,11

思路:如果矩形X包含在矩形Y中,我们就从矩形X到Y连一条有向边;N个结点构成一个有向无环图DAG,我们的任务就是求DAG上的最长路径。

设d(i)表示从结点i出发的最长路径长度,则d(i)=max[d(j)+1|(i,j)∈E],其中E为边集。最终答案为所有d(i)中的最大值。

根据状态转移方程,可以尝试递推或记忆化搜索求解。对于状态递推顺序不容易确定时,记忆化搜索更方便一些。当终点固定时,递推更方便一些。

import java.util.Arrays;
import java.util.Scanner;

public class Main {
	public static int dpSolution(int[][] edg,int[] d,int index){
		if(d[index]>=0)
			return d[index];
		d[index]=1;
		for(int i=0;i<edg.length;i++){
			if(edg[index][i]==1){
				int temp=dpSolution(edg,d,i)+1;
				if(temp>d[index])
					d[index]=temp;
			}
		}
		return d[index];
	}
	public static void print(int[][] a,int[][] edg,int[] d,int index){
		System.out.println(a[index][0]+","+a[index][1]);
		for(int i=0;i<d.length;i++){
			if(edg[index][i]==1&&d[index]-d[i]==1){
				print(a,edg,d,i);
				break;
			}
		}
	}
	public static void main(String[] args){
		Scanner scanner = new Scanner(System.in);
		while(scanner.hasNext())
		{
			int n=scanner.nextInt();
			scanner.nextLine();
			int[][] a=new int[n][2];
			int[][] edg=new int[n][n];
			int[] d=new int[n];
			Arrays.fill(d, -1);
			for(int i=0;i<n;i++){
				String s=scanner.nextLine();
				String[] temp=s.split(",");
				a[i][0]=Integer.parseInt(temp[0]);
				a[i][1]=Integer.parseInt(temp[1]);
			}
			for(int i=0;i<n;i++){		//用邻接矩阵存储各个矩形的包含关系
				for(int j=i+1;j<n;j++){
					if((a[i][0]<a[j][0]&&a[i][1]<a[j][1])||(a[i][1]<a[j][0]&&a[i][0]<a[j][1])){
						edg[i][j]=1;
					}else if((a[i][0]>a[j][0]&&a[i][1]>a[j][1])||(a[i][1]>a[j][0]&&a[i][0]>a[j][1])){
						edg[j][i]=1;
					}
				}
			}
			for(int i=0;i<n;i++){
				dpSolution(edg, d, i);
			}
			int max=0,num=0;
			for(int i=0;i<n;i++){
				if(d[i]>max){
					max=d[i];
					num=i;
				}
			}
			print(a,edg,d,num);
		}
		scanner.close();
	}
}


<think> 首先,用户的问题是:“我想查找使用Java语言输出矩形的方法 请问Java语言输出矩形的实现方法”。基于系统指令,我需要使用中文回答。 现在,用户提供了几个引用: - 引用[1]:Java用for循环打印矩形。代码示例使用Scanner获取输入,然后嵌套for循环打印*来形成矩形。 - 引用[2]:Java代码实现矩形类。这是一个类定义,包含width和height,以及计算面积和周长的方法。 - 引用[3]:Java使用带返回值的方法求矩形面积并输出。用户输入长和宽,计算面积并输出。 用户说:“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。” 但在对话历史中,用户上次的问题是:“我想查找使用Java语言输出矩形的方法”。所以,我需要专注于回答如何输出矩形。 我的回答需要结构化清晰,帮助用户逐步解决问题。系统指令要求生成相关问题。 关键点:用户问的是“输出矩形”,不是计算面积或周长。引用[1]直接展示了如何打印一个矩形形状,比如用*组成的矩形。引用[2]和[3]是关于矩形类的实现和面积计算,并不直接输出矩形形状。 所以,我应该强调如何打印矩形的形状,使用for循环打印字符(如*)。 回答结构: 1. **介绍基本方法**:使用嵌套for循环打印矩形。外层循环控制行数(高度),内层循环控制每行的字符数(宽度)。 2. **提供代码示例**:基于引用[1],展示一个简单的Java程序,用户可以输入长和宽,然后打印矩形。 3. **解释关键点**: - 使用`System.out.print("*")`来打印一个星号而不换行。 - 使用`System.out.println()`来换行。 - 提醒print和println的区别。 4. **引用支持**:在回答中自然地添加引用标识,如[^1]。 5. **生成相关问题**:在末尾添加相关问题,基于系统指令。 相关问题可以包括: - 如何优化打印矩形? - 如何打印空心矩形? - 如何将矩形打印封装成方法或类? - 其他相关主题如计算面积。 最终回答: - 先简述方法。 - 提供代码示例(用代码块格式)。 - 解释代码。 - 添加引用。 - 最后生成相关问题。 </think> 以下是针对您查询的“Java语言输出矩形的实现方法”的详细解答。我将参考您提供的站内引用(特别是引用[1]),专注于如何使用Java打印矩形的形状(即以字符如`*`组成的矩形图案)。核心方法是使用嵌套for循环:外层循环控制行数(高度),内层循环控制每列宽度(长度),并使用`System.out.print()`和`System.out.println()`方法来输出字符而不换行或换行[^1]。回答结构清晰,分步解释,并提供完整代码示例。 ### 1. **基本实现方法** Java输出矩形形状的核心步骤如下: - **获取用户输入**:使用`Scanner`类从用户处获取矩形的长度(列数)和宽度(行数)。 - **嵌套for循环**: - 外层循环(例如`for (int i = 1; i <= height; i++)`):控制矩形的行数(高度)。 - 内层循环(例如`for (int j = 1; j <= length; j++)`):控制每行的字符数(长度),打印连续的字符如`*`。 - **输出控制**: - `System.out.print("*")`:打印一个星号,但不换行,用于构建矩形的行。 - `System.out.println()`:在每行结束后换行,确保矩形形状正确。 - **关键区别**:`print`用于不换行输出,而`println`在输出后添加换行符[^1]。 ### 2. **完整代码示例** 以下Java程序基于引用[1]的实现,用户输入长和宽后,打印一个实心矩形(由`*`组成)。代码注释详细解释了每一步: ```java import java.util.Scanner; // 导入Scanner类以获取用户输入 public class PrintRectangle { public static void main(String[] args) { // 创建Scanner对象读取用户输入 Scanner sc = new Scanner(System.in); System.out.println("请输入矩形的宽度(行数):"); int height = sc.nextInt(); // 宽度对应行数(高度) System.out.println("请输入矩形的长度(列数):"); int length = sc.nextInt(); // 长度对应列数(宽度) // 嵌套for循环打印矩形 for (int i = 1; i <= height; i++) { // 外层循环:控制行(高度) for (int j = 1; j <= length; j++) { // 内层循环:控制每行的列(长度) System.out.print("*"); // 打印星号,不换行 } System.out.println(); // 每行结束后换行 } sc.close(); // 关闭Scanner对象以释放资源 } } ``` #### **代码说明** - **运行示例**: - 如果用户输入宽度=3(行数)、长度=5(列数),输出将是一个3行5列的矩形: ``` ***** ***** ***** ``` - **关键点**: - **print vs println**:`System.out.print("*")`确保星号在同一行连续打印,而`System.out.println()`在行尾换行,避免形状错位[^1]。 - **用户友好**:程序提示用户输入,并通过循环动态生成矩形形状。 - **注意事项**: - 如果输入负数或零,程序可能输出空或不正确结果。您可以通过添加输入验证来优化(例如,使用if语句检查输入值是否为正)。 - 此方法打印的是实心矩形;稍加修改可扩展为空心矩形或其他图案(见下文相关问题)。 ### 3. **其他方法的参考** 虽然您的查询聚焦于“输出矩形形状”,但引用[2]和[3]介绍了矩形类和方法封装,适用于计算属性(如面积),而非直接打印形状。如果您需要结合形状输出和属性计算,我可以基于这些引用提供扩展方案: - **引用[2]**:定义一个`Rectangle`类,包含`width`和`height`字段,并可添加`printShape()`方法来封装打印逻辑[^2]。 - **引用[3]**:使用带返回值的方法获取用户输入并计算面积,但需修改为调用打印方法[^3]。 ### 4. **常见问题解答** - **Q: 程序输出不换行怎么办?** A: 确保在内层循环后使用`System.out.println()`,而不是`System.out.print()`。误用会导致所有星号打印在一行[^1]。 - **Q: 如何打印空心矩形?** A: 修改内层循环逻辑:只在第一行、最后一行或第一列、最后一列打印`*`,其他位置打印空格。例如: ```java for (int i = 1; i <= height; i++) { for (int j = 1; j <= length; j++) { if (i == 1 || i == height || j == 1 || j == length) { System.out.print("*"); // 边框打印星号 } else { System.out.print(" "); // 内部打印空格 } } System.out.println(); } ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值