2018暑假校内第一次比赛

本文介绍了一种解决特定网格路径问题的方法,通过预处理连乘并结合动态规划技术,找到从左上角到右下角的路径,使得该路径所构成的数学表达式的计算结果最大。介绍了核心算法思想及实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Route Calculator
Time Limit: 10000ms, Special Time Limit:25000ms, Memory Limit:524288KB
Total submit users: 9, Accepted users: 2
Problem 14108 : No special judgement
Problem description
You have a grid with H rows and W columns. H+W is even. We denote the cell at the i-th row from the top and the j-th column from the left by (i,j). In any cell (i,j), an integer between 1 and 9 is written if i+j is even, and either '+' or '*' is written if i+j is odd.
You can get a mathematical expression by moving right or down H+W-2 times from (1,1) to (H,W) and concatenating all the characters written in the cells you passed in order. Your task is to maximize the calculated value of the resulting mathematical expression by choosing an arbitrary path from (1,1) to (H,W). If the maximum value is 1015 or less, print the value. Otherwise, print -1.
 
Input
The input consists of a single test case in the format below.
H W
a1,1...a1,W
...
aH,1...aH,W
The first line consists of two integers H and W(1 ≤ H,W ≤ 50). It is guaranteed that H+W is even. The following H lines represent the characters on the grid. ai,j represents the character written in the cell (i,j). In any cell (i,j), an integer between 1 and 9 is written if i+j is even, and either '+' or '*' is written if i+j is odd.
 
Output
Print the answer in one line.
 
Sample Input
Sample Input 1
3 3
1+2
+9*
1*5

Sample Input 2
1 31
9*9*9*9*9*9*9*9*9*9*9*9*9*9*9*9

Sample Input 3
5 5
2+2+1
+1+1+
1+2+2
+1+1+
1+1+2

Sample Input 4
9 7
8+9*4*8
*5*2+3+
1*3*2*2
*5*1+9+
1+2*2*2
*3*6*2*
7*7+6*5
*5+7*2+
3+3*6+8
Sample Output
Output for Sample Input 1
46

Output for Sample Input 2
-1

Output for Sample Input 3
10

Output for Sample Input 4
86408
Judge Tips
The 1st case,The maximum value is obtained by passing through the following cells:(1,1) ,(2,1) ,(2,2) ,(2,3) ,(3,3) .
The 2nd case,You can obtain 916, but it's too large.
 
Problem Source
JAG Practice Contest for ACM-ICPC Asia Regional 2017, AtCoder, 2017-09-24

题意:有一个n*m的矩阵,矩阵由数字和+,*组成,保证数字周围是运算符,运算符周围是数字,求一条路径从左上角到右上角,运算结果最大,注意如果结果大于1e15输出-1

题解:本题跟CCF的走大路走小路很类似,首先我们将连乘预处理,得到(i,j) -> (u, v)连乘的最大值,然后进行一次简单dp即可。

我们用a[i][j][k][l]记录从(i, j)到(k,l)连乘的最大值,用b[i][j]记录从起点到(i, j)的最大值,c[i][j]记录原矩阵的值,则对于当前点(i,j)我们可以得到,如果其左边有加号,则取b[i - 1][j - 1]和b[i][j - 2]的较大值,若上面有加号,则取b[i - 1][j - 1][i - 2][j]的较大值,将之前取得的较大值再取较大值,与c[i][j]相加更新当前的b[i][j], 同时如果之前有点能连乘到(i, j),假设其为(u, v),则用

b[u][v] - c[u][v] + a[u][v][i][j]来跟当前b[i][j]比较,取较大值

以上

AC代码

#include <stdio.h>
#include <iostream>
#include <queue>
#define ll __int64

using namespace std;

const ll maxn = 55, inf = 1e15;
char map1[maxn][maxn];
ll a[maxn][maxn][maxn][maxn] = {0}, b[maxn][maxn], c[maxn][maxn], d[maxn][maxn], vis[55 * 55] = {0};
vector<ll> s[55 * 55];

bool shu(char x){
	if(x >= '0' && x <= '9')
		return true;
	return false;
}

int main(){
	ll n, m;
	scanf("%I64d %I64d", &n, &m);
	for(ll i = 0; i < n; i++){
		scanf("%s", map1[i]);
		for(ll j = 0; j < m; j++){
			if(map1[i][j] >= '0' && map1[i][j] <= '9'){
				b[i][j] = a[i][j][i][j] = c[i][j] = map1[i][j] - '0';
			}
		}
	}
	for(ll i = 0; i < n; i++){
		for(ll j = 0; j < m; j++){
			for(ll k = i; k < n; k++){
				for(ll l = j; l < m; l++){
					if(shu(map1[i][j]) && shu(map1[k][l]) && (k != i || l != j)){
						ll temp = 1;
						ll ff = 0;
						if(k - 1 >= i && map1[k - 1][l] == '*'){
							if(k - 2 >= i){
								temp = max(temp, a[i][j][k - 2][l]);
							}
							ff = 1;
						}
						if(l - 1 >= j && map1[k][l - 1] == '*'){
							if(l - 2 >= j){
								temp = max(temp, a[i][j][k][l - 2]);
							}
							ff =1;
						}
						if((l - 1 >= j) && (k - 1 >= i) && (map1[k - 1][l] == '*' || map1[k][l - 1] == '*')){
							temp = max(temp, a[i][j][k - 1][l - 1]);
							ff = 1;
						}
						if(ff == 0)
							continue;
						a[i][j][k][l] = b[k][l] * temp;
						if(a[i][j][k][l] > inf){
							printf("-1");
							return 0;
						}
						if(temp != 1){
							s[k * maxn + l].push_back(i * maxn + j);
						}
					}
				}
			}
		}
	}
	for(ll i = 0; i < n; i++){
		for(ll j = 0; j < m; j++){
			ll temp = 0;
			if(!shu(map1[i][j]))
				continue;
			if(i - 1 >= 0 && map1[i - 1][j] == '+'){
				if(i - 2 >= 0){
					temp = max(temp, c[i][j] + b[i - 2][j]);
				}
			}
			if(j - 1 >= 0 && map1[i][j - 1] == '+'){
				if(j - 2 >= 0){
					temp = max(temp, c[i][j] + b[i][j - 2]);
				}
			}
			if(j - 1 >= 0 && i - 1 >= 0 && (map1[i - 1][j] == '+' || map1[i][j - 1] == '+')){
				temp = max(temp, c[i][j] + b[i - 1][j - 1]);
			}
			if(s[i * maxn + j].size()){
				for(int k = 0; k < s[i * maxn + j].size(); k++){
					int v = s[i * maxn + j][k];
					temp = max(temp, b[v / maxn][v % maxn] - c[v/maxn][v%maxn] + a[v / maxn][v % maxn][i][j]);
				}
			}
			b[i][j] = max(temp, c[i][j]);
			if(b[i][j] > inf){
				printf("-1\n");
				return 0;
			}
		}
	}
	printf("%I64d\n", b[n - 1][m - 1]);
	return 0;
}

 

<think>好的,我现在需要处理用户关于中南民族大学Web程序设计第一次实验的查询。首先,用户希望找到相关的实验资料、要求、指导或教程。根据用户提供的引用内容,我需要先检查是否有直接相关的信息。 查看引用内容,引用[1]提到系统的结构分为浏览器端、web服务器端、数据库和文件系统,这可能与Web程序设计的基础知识相关。引用[2]是关于SpringBoot和Vue框架的数据库原理网站设计,虽然不直接对应,但可能涉及Web开发的技术栈。引用[3]讨论的是模型训练和服务发布,可能不相关。引用[4]是关于Android网络编程和XML解析,可能与Web实验中的前端技术有关联,比如XML在Web中的应用。 接下来,用户需要的是实验报告的要求、指导和教程。由于现有引用中没有直接提到中南民族大学的实验内容,可能需要根据常见的Web程序设计实验结构来推测。通常第一次实验可能涉及HTML/CSS基础、服务器配置、简单页面开发等。例如,创建用户登录页面、实现表单提交等,这可能与引用[1]中的浏览器端和服务器端交互有关。 另外,引用[4]中提到的XML解析可能在实验的数据处理部分有用,比如解析配置文件。不过需要结合Web开发的实际应用。此外,引用[2]中的SpringBoot和Vue框架可能属于进阶内容,第一次实验可能更基础,比如使用基础的HTML、JavaScript和Servlet/JSP技术。 建议用户参考学校提供的官方资料,联系指导老师,或在课程平台查找资源。如果实验涉及具体技术点,如DOM操作、服务器请求处理,可以结合引用中的相关内容进行解释。同时,提醒用户注意实验的具体要求,如是否需要使用特定框架或工具,确保符合实验目标。</think>### 中南民族大学 Web程序设计 第一次实验 相关指导 根据实验课程的常见设计模式以及引用内容中的技术框架,推测第一次实验可能涉及以下内容: #### 1. **实验要求与目标** - **基础目标**:通常首次实验会要求搭建简单的Web页面,实现用户登录/注册界面,并完成前后端数据交互[^1][^4]。 - **技术要求**: - 使用HTML/CSS编写静态页面(如登录表单)。 - 通过JavaScript或框架(如Vue)实现动态交互[^2]。 - 后端使用Java(如SpringBoot)或PHP处理请求,连接数据库存储数据[^1]。 #### 2. **实验步骤参考** **步骤1:搭建前端页面** - 使用HTML创建表单,例如: ```html <form id="loginForm"> <input type="text" name="username" placeholder="用户名"> <input type="password" name="password" placeholder="密码"> <button type="submit">登录</button> </form> ``` - 通过CSS美化界面,添加响应式布局。 **步骤2:实现前后端通信** - 使用JavaScript或AJAX提交表单数据到后端(如SpringBoot的`@RestController`): ```javascript document.getElementById("loginForm").addEventListener("submit", async (e) => { e.preventDefault(); const response = await fetch("/api/login", { method: "POST", body: new FormData(e.target) }); const result = await response.json(); console.log(result); }); ``` **步骤3:后端逻辑与数据库连接** - 后端接收请求并验证数据(示例为Java SpringBoot): ```java @PostMapping("/api/login") public ResponseEntity<?> login(@RequestParam String username, @RequestParam String password) { // 查询数据库验证用户信息 if (isValidUser(username, password)) { return ResponseEntity.ok("登录成功"); } return ResponseEntity.status(401).body("用户名或密码错误"); } ``` #### 3. **实验报告要求** - **内容结构**: 1. 实验目的:简述Web开发基础流程。 2. 实验环境:如开发工具(VS Code、IntelliJ IDEA)、技术栈(HTML/Vue/SpringBoot)。 3. 核心代码与注释:需标注关键逻辑(如表单验证、数据库查询)。 4. 运行结果:截图展示页面效果及功能演示。 5. 问题分析:记录调试过程中遇到的错误(如跨域问题、数据库连接失败)及解决方法[^4]。 #### 4. **学习资源推荐** - **校内资源**:联系课程教师获取实验模板或参考往届资料(部分学校会提供示例代码)。 - **技术文档**: - Vue官方教程(实现动态前端)。 - SpringBoot数据库操作(整合MyBatis或JPA)。 - **调试工具**:浏览器开发者工具(Network面板监控请求)、Postman测试API。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值