前言
因为周六要打工没空,所以选择参加了11.10号的场次,在参加之前我除了知道这两场题目会不同之外,我还发现11.9对于编程语言限制的描述是
Q1
第一道题是定义了一个完美平方数组,他会给你字符串的长度,以及相对应的由01组成的字符串,如果他能形成一个m * n的矩阵,满足外部都是1,中间都是0,就是完美数组,且当m == n的时候,是完美平方数组。输入的格式先是字符串的个数,然后接受每个字符串的长度和内容,满足完美平方数组的打印Yes,否则打印No。
Q2
第二道题是会给出一个表达式,然后你要做的是解析表达式,解析成功的打印表达式的最终值,解析失败则打印XXX。要求解析的只有+-*/,且输入可能会有空格。
Q3
第三道题是给定一个包含非负整数的 m x n
矩阵 ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。且元素为0时,表示不可以通过。说明:每次只能向下或者向右移动一步。
我的思路
第一题的话我是先判断是否满足平方,然后再简单的遍历每一个字符串的元素是否满足0,1的条件。
第二题用了两个栈来解析,第一个栈对于数字操作,第二个对于op符操作,当遇到数字进数字栈,遇到符号且符号栈为空时进栈,栈不为空时,根据符号的优先级进行出栈以及计算的判断。不过中间会有一些细节的处理。
第三题是很常见的dp题,因为某一点的最短路径只会来自于他的左边和上边,选择短的加上自己则是最短,所以可以划分为子问题。不过这里要对于0做特殊处理,我的处理是将此处的dp值设为int的最大值。随后循环生成打印即可。
代码如下:
#include <algorithm>
#include <iostream>
using namespace std;
int main() {
int n,m;
cin >> m >> n;
int arr[100][100];
for(int i = 0 ;i < m; i++){
for(int j = 0; j < n; j++){
cin >> arr[i][j];
}
}
int dp[100][100] = {0};
dp[0][0] = arr[0][0];
for(int i = 1 ;i < m; i++){
if(arr[i][0] == 0){
while(i < m){
dp[i][0] = INT32_MAX;
i++;
}
}else{
dp[i][0] = dp[i - 1][0] + arr[i][0];
}
}
for(int i = 1 ;i < n; i++){
if(arr[0][i] == 0){
while(i < n){
dp[0][i] = INT32_MAX;
i++;
}
}else {
dp[0][i] = dp[0][i - 1] + arr[0][i];
}
}
for(int i = 1 ;i < m; i++){
for(int j = 1; j < n; j++){
if(arr[i][j] == 0){
dp[i][j] = INT32_MAX;
}else {
dp[i][j] = min(dp[i - 1][j], dp[i][j - 1]) + arr[i][j];
}
}
}
printf("%d",dp[m - 1][n - 1]);
}
总结
只有第三题的代码的原因是,我没有在本地idea存储每一题的答案,所以只剩下最后的,就顺便贴上了。对于这次笔试,我得了60分,最后一题没有AC,可能还是因为我平常不会经常去有目的性的去刷题,所以做题目的速度比较慢,导致最后只差一点点但是来不及写完了。我做题的过程首先就是思路的产生,再到将思路转化为实践,最后是实践中的边界情况讨论。第一题我就写了半个小时,要花费很多时间去找到出错的边界。第二题也是一样的情况,写完第二题只剩半个小时了。而第三题一开始我甚至没看到障碍的情况,导致虽然找到了问题的核心,但距离写出题目浪费了很多时间,最后找到原因之后也已经来不及了,虽然最后还是花了几分钟把它写完了,不过算是有点可惜。
感觉除了平常的科研和学习,还是可以花一点时间来规划一下这种题目的训练,毕竟以后也会用得上,这次笔试的体验总体来说还是很不错的,继续努力吧。