试题 算法训练 逗志芃的暴走 java实现

问题描述
  逗志芃是有妹子的现充,但是有时候妹子就是烦恼。因为逗志芃太逗了,所以这段时间妹子对逗志芃发动了技能无理取闹,妹子要去玩很多的景点。由于逗志芃之前抽机花费了太多的时间,不久以后又要微积分考试了,所以现在被妹子搞成暴走状态了。但是妹子永远是上帝,所以逗志芃只能带妹子出去玩,不过为了节约时间,他希望找到一条花费时间最少的一次性游览线路。
输入格式
  第一行1个数n,表示逗志芃所在的城市有多少个景点,接下来是一个n*n的矩阵。a(i,j)表示i号景点到j号景点的路上花费的时间是多少。
  接下来是一个数m,表示逗志芃妹子要去去的景点数目。由于妹子在无理取闹,所以可能会有重复的景点,不过只要去一次就可以了。接下来是m个数,就是妹子要去的景点编号。
输出格式
  一个数,最少的花费时间。
样例输入
3
0 1 2
1 0 3
2 3 0
3
2 3 1
样例输出
3
数据规模和约定
  0<n<=30,0<m<=20,时间<=1000000

解题思路:利用Floyd算法将点与点之间的最短路径算出来,然后再对要去的景点dfs计算最优解(遍历完后的最优解是不会走重复的点的)


import java.util.Scanner;

//有重复的点
public class Main {
	static int n, m;// n代表n行n列 m代表旅游景点个数
	static int[][] map = new int[31][31];// 存储给定的景点之间的距离
	static int[] vis = new int[31];// 存储景点的状态,0是没有走过的,1是已经走过
	static int[] b = new int[21];// m个输入要去的景点
	static int ans = Integer.MAX_VALUE;// 最终最短路径长度

	public static void main(String[] args) {
		Scanner scanner = new Scanner(System.in);
		n = scanner.nextInt();
		for (int i = 1; i <= n; i++) {
			for (int j = 1; j <= n; j++) {
				map[i][j] = scanner.nextInt();
			}
		}
		floyd();// 进行floyd计算点与点之间的最短距离
		m = scanner.nextInt();
		for (int i = 1; i <= m; i++) {
			b[i] = scanner.nextInt();
		}
		// 进行dfs搜索
		for (int i = 1; i <= m; i++) {// 遍历要去的景点
			vis[b[i]] = 1;// 将第一个点状态置1
			dfs(b[i], 0);
			vis[b[i]] = 0;// 恢复状态
		}
		System.out.println(ans);
	}

	// 利用Floyd算法得出点到点之间的最优解
	public static void floyd() {
		for (int k = 1; k <= n; k++) {// 中间点
			for (int i = 1; i <= n; i++) {// 起始点
				for (int j = 1; j <= n; j++) {// 终点
					map[i][j] = Math.min(map[i][j], map[i][k] + map[k][j]);
				}
			}
		}
	}

	public static void dfs(int u, int length) {

		boolean flag = true;// 结束的标志
		for (int i = 1; i <= m; i++) {// 遍历所有要去的景点的状态,如果都是1说明已经都走过了,就结束。
			if (vis[b[i]] == 0) {// 找到还有没走的景点
				flag = false;// 修改结束标志
				break;// 跳出循环
			}
		}

		if (flag) {// 结束则判断之前的路径和当前路径的大小,取较小值
			ans = Math.min(ans, length);
			return;
		}
		for (int i = 1; i <= m; i++) {// 没有结束则遍历要去的景点
			if (vis[b[i]] == 0 && length + map[u][b[i]] <= ans) {// 判断景点是否去过,到下一个景点的距离长度小于当前最佳路径的值,才考虑走这个点
				vis[b[i]] = 1;// 将景点状态置1
				dfs(b[i], length + map[u][b[i]]);// 寻找下一个点
				vis[b[i]] = 0;// 恢复景点状态
			}

		}
	}
}

提交结果:
在这里插入图片描述

dfs代码应该可以优化,两个循环可以写成一个,不过要思考结束条件,就不想了,嘿嘿。

可以使用 Java Servlet 和 JSP 技术实现一个简单的登录系统。首先,需要创建一个登录页面,用户可以在该页面输入用户名和密码。然后,将用户输入的用户名和密码发送到服务器端进行验证。如果验证通过,就将用户重定向到主页;否则,就返回登录页面并显示错误消息。以下是一个简单的登录系统的示例代码: login.jsp: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Login</title> </head> <body> <h1>Login</h1> <form action="login" method="post"> <label>Username:</label> <input type="text" name="username"><br> <label>Password:</label> <input type="password" name="password"><br> <input type="submit" value="Login"> </form> </body> </html> ``` LoginServlet.java: ``` import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @WebServlet("/login") public class LoginServlet extends HttpServlet { private static final long serialVersionUID = 1L; protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username"); String password = request.getParameter("password"); if ("admin".equals(username) && "password".equals(password)) { response.sendRedirect("home.jsp"); } else { request.setAttribute("error", "Invalid username or password"); request.getRequestDispatcher("login.jsp").forward(request, response); } } } ``` home.jsp: ``` <%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>Home</title> </head> <body> <h1>Welcome!</h1> </body> </html> ``` 在这个示例中,我们使用了 Java Servlet 和 JSP 技术实现了一个简单的登录系统。用户可以在 login.jsp 页面输入用户名和密码,然后将这些信息发送到 LoginServlet 进行验证。如果验证通过,就将用户重定向到 home.jsp 页面;否则,就返回 login.jsp 页面并显示错误消息。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值