回溯法:机器人的活动范围
回溯法与深度优先搜索以及枚举法是经典的暴力三大法(我1min前发明的,虽然本质上是一个东西),所谓 “遇事不决暴力解,能A几个算几个”更是做题界的至理名言(我30s秒前发明的)。回溯是隐式图的深搜,深搜是图论上的枚举,所以使用回溯法的时候,能剪枝的地方一个不要漏,否则你就成无脑暴力男了。
回溯法介绍
我都查不到几篇讲回溯法的,大概大家都以暴力为耻吧(⊙﹏⊙)……
https://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html
解题:机器人的活动范围
地上有一个m行和n列的方格。一个机器人从坐标0,0的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于k的格子。 例如,当k为18时,机器人能够进入方格(35,37),因为3+5+3+7 = 18。但是,它不能进入方格(35,38),因为3+5+3+8 = 19。请问该机器人能够达到多少个格子?
我知道这个题很白痴,我只是想练练手,我才不会告诉你我又改了两个小时的bug呢~?
我还研究了好久的二维数组做参数,最后的结论是:还是一维数组好用
#include <iostream>
#include <stack>
#include <time.h>
#include <stdlib.h>
using namespace std;
int calu(int a)
{
int sum = 0;
do{
sum += a%10;
a = a/10;
}while(a > 0);
return sum;
}
int findPath(int x, int y, bool* visted,int threshold, int rows, int cols,int floor)
{
int count = 0;
if ((visted[x*cols+y] == true) || x >= rows ||y >= cols||x<0||y<0||calu(x) + calu(y) > threshold)
return 0;
visted[x * cols + y] = true;
count = 1 +
findPath(x + 1, y , visted, threshold, rows, cols,floor+1) +
findPath(x, y + 1, visted, threshold, rows, cols,floor+1) +
findPath(x - 1, y , visted, threshold, rows, cols,floor+1) +
findPath(x, y - 1, visted, threshold, rows, cols,floor+1);
printf("%d %d %d %d\n",x, y, count, floor);
return count;
}
int movingCount(int threshold, int rows, int cols)
{
bool* visted = new bool[rows*cols];
for(int i = 0;i<rows*cols;i++)
visted[i] = false;
int count = findPath(0,0,visted, threshold, rows, cols, 0);
int a = 0;
for(int i = 0;i<rows*cols;i++)
if(visted[i] == true)
a++;
delete[] visted;
return count;
}
int main()
{
int a, b, c;
cin>>a>>b>>c;
cout<< movingCount(a,b,c)<<endl;
}
私企都是水深火热呀,种树+6