【华为机试题解】奥特曼打怪兽

大概题意

在一个N*N的正方形区域,每个小格可能有三种状态
值为0,正常可通过
值为1,奥特曼可通过,同时还可以消灭怪兽,消灭后值变为0,消灭怪兽数量+1
值为-1,有大石头,奥特曼无法通过

奥特曼需要先从上往下走,这个过程只能向下或者向右,到达右下角后,再从下往上走,这个过程只能向左或向上。需要找到奥特曼可以消灭怪兽的最大数量

输入:
第一行一个N,表示N的正方形区域的大小,N不超过50
第二行到N+1行,每一行N个数,表示正方形区域的情况

输出:
奥特曼可以消灭怪兽的最大数量

思路

1、和以前的动态规划很像,但是好像是不能用动态规划。(leetcode 741打脸了)
2、回溯,本题给C++的时间是2秒,一般都是1秒,说明可以走高复杂度策略

心情

考试的时候没写出来,考完后写出来了,就是这种心情

代码

#include <bits/stdc++.h>
using namespace std;
const int MAX = 60;

void walkup(int gird[MAX][MAX], int i, int j, int N, int tempAns, int& trueAns){
	if(i == 0 && j == 0){
		if(trueAns < tempAns){
			trueAns = tempAns;
		}
	}
	else if(i == 0){
		if(gird[i][j] == 0){
			walkup(gird, i, j-1, N, tempAns, trueAns);
		}
		else if(gird[i][j] == 1){
			gird[i][j] = 0;
			walkup(gird, i, j-1, N, tempAns+1, trueAns);
			gird[i][j] = 1;
		}
	}
	else if(j == 0){
		if(gird[i][j] == 0){
			walkup(gird, i-1, j, N, tempAns, trueAns);
		}
		else if(gird[i][j] == 1){
			gird[i][j] = 0;
			walkup(gird, i, j-1, N, tempAns+1, trueAns);
			gird[i][j] = 1;
		}
	}
	else{
		if(gird[i][j] == 0){
			walkup(gird, i-1, j, N, tempAns, trueAns);
			walkup(gird, i, j-1, N, tempAns, trueAns);
		}
		else if(gird[i][j] == 1){
			gird[i][j] = 0;
			walkup(gird, i-1, j, N, tempAns+1, trueAns);
			walkup(gird, i, j-1, N, tempAns+1, trueAns);
			gird[i][j] = 1;
		}
	}
}


void walkdown(int gird[MAX][MAX], int i, int j, int N, int tempAns, int& trueAns){
	if(i == N-1 && j == N-1){
		if(gird[i][j] == 0){
			walkup(gird, i-1, j, N, tempAns, trueAns);
			walkup(gird, i, j-1, N, tempAns, trueAns);
		}
		else if(gird[i][j] == 1){
			walkup(gird, i-1, j, N, tempAns+1, trueAns);
			walkup(gird, i, j-1, N, tempAns+1, trueAns);
		}
	}
	else if(i == N-1){
		if(gird[i][j] == 0){
			walkdown(gird, i, j+1, N, tempAns, trueAns);
		}
		else if(gird[i][j] == 1){
			gird[i][j] = 0;
			walkdown(gird, i, j+1, N, tempAns+1, trueAns);
			gird[i][j] = 1;
		}
	}
	else if(j == N-1){
		if(gird[i][j] == 0){
			walkdown(gird, i+1, j, N, tempAns, trueAns);
		}
		else if(gird[i][j] == 1){
			gird[i][j] = 0;
			walkdown(gird, i+1, j, N, tempAns+1, trueAns);
			gird[i][j] = 1;
		}
	}
	else{
		if(gird[i][j] == 0){
			walkdown(gird, i+1, j, N, tempAns, trueAns);
			walkdown(gird, i, j+1, N, tempAns, trueAns);
		}
		else if(gird[i][j] == 1){
			gird[i][j] = 0;
			walkdown(gird, i+1, j, N, tempAns+1, trueAns);
			walkdown(gird, i, j+1, N, tempAns+1, trueAns);
			gird[i][j] = 1;
		}
	}
}

int main()
{
	int gird[MAX][MAX];
	int dp[MAX][MAX];
	for(int i = 0; i < MAX; i++){
		for(int j = 0; j < MAX; j++){
			gird[i][j] = 0;
			dp[i][j] = 0;
		}
	}
	int N;
	cin >> N;
	for(int i = 0; i < N; i++){
		for(int j = 0; j < N; j++){
			cin >> gird[i][j];
		}
	}
	
	// 从上往下走
//	for(int i = 0; i < N; i++){
//		for(int j = 0; j < N; j++){
//			if(gird[i][j] == 0){
//				dp[i][j] = dp[i][j-1] > dp[i-1][j] ? dp[i][j-1] : dp[i-1][j];
//			}
//			else if(gird[i][j] == 1){
//				dp[i][j] = dp[i][j-1] > dp[i-1][j] ? dp[i][j-1] : dp[i-1][j];
//				dp[i][j]++;
//			}
//			else{
//				dp[i][j] = -1;
//			}
//		}
//	}
	
	int tempAns = 0;
	int trueAns = 0;
	walkdown(gird, 0, 0, N, tempAns, trueAns);
	cout << trueAns << endl;
	
	return 0;
}
发布了164 篇原创文章 · 获赞 26 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/u013095333/article/details/91902270