在上次的刷题记中分别体验了easy和medium难度,感觉easy属于纯水题,medium属于技巧性。那么,这次当然要来体验一下hard难度
675. Cut Off Trees for Golf Event
难度:
Hard
思路:
图论题,其实题意也十分清晰,在一个种满树的的矩阵中,按照树的高度从小到大依次砍树,求最短距离。
图论最短距离的搜索当然要数bfs了,对于搜索顺序,对树预处理排序即可。
可见这题的难度并不是在于思路上,而是对bfs的coding上。
STL知识回顾:
stack:
stack<element>
LIFO
stl的stack默认基于deque实现,但其实也能在声明的时候手动改成list,array或者list实现,但基本操作并不会增加,所以并没有什么太大区别。
stack基本操作主要有:插入push(),弹出pop(),查询栈顶top(),判空empty(),清空clear(),查询大小size()
stack支持复制已有stack进行构造,但不支持遍历的iterator
弹出函数pop()无返回值,一般与栈顶函数top()结合使用
queue:
queue<element>
FIFO
queue和stack基本功能和实现基本一模一样,只有基本操作有一点小小区别
queue基本操作也有:插入push(),弹出pop(),判空empty(),清空clear(),查询大小size()
不过pop()弹出的是队首元素而不是栈顶元素
此外还有front()和back()这两个查询队首和对位的操作
sort:
sort<struct>
这部分主要想说一下sort对自定义结构体的排序。
一般情况可以通过往sort中塞cmp函数实现,但由于leetcode中无法在class类定义cmp,于是这次简要说说直接在结构体中重载小于号来实现,因为sort默认从小到大排序
/*
Author Owen_Q
*/
typedef struct DataStruct
{
int variable, variable_used_for_sort;
bool operator < (const struct DataStuct& dts) const
{
if(variable_used_for_sort < dts.variable_used_for_sort)
return true;
else
return false;
}
}Ds;
代码:
/*
Author Owen_Q
*/
class Solution {
public:
int cutOffTree(vector<vector<int>>& forest) {
m = forest[0].size();
n = forest.size();
aim.clear();
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(forest[i][j]>1)
{
Point temp;
temp.x = i;
temp.y = j;
temp.h = forest[i][j];
aim.push_back(temp);
}
//cout << forest[i][j] << " ";
}
//cout << endl;
}
sort(aim.begin(),aim.end()/*,cmp*/);
int sum = 0;
int len = aim.size();
pair<int,int> nowPoint = make_pair(0,0);
for(int i=0;i<len;i++)
{
//cout << aim[i].x << "*" << aim[i].y << " ";
int re = bfs(nowPoint,make_pair(aim[i].x,aim[i].y), forest);
//cout << re << endl;
if(re>=0)
{
sum += re;
nowPoint = make_pair(aim[i].x,aim[i].y);
}
else
{
sum = -1;
break;
}
}
return sum;
}
private:
typedef struct POINT
{
int x, y, h;
bool operator < (const struct POINT& rhs) const
{
if(h<rhs.h)
return true;
else
return false;
}
}Point;
/* bool cmp(const Point& a, const Point& b)
{
if(a.h<b.h)
return true;
else
return false;
}*/
typedef struct STEP
{
int x,y,s;
}Step;
vector<Point> aim;
int m;
int n;
bool legalPoint(Step p)
{
if(p.x<0||p.x>=n||p.y<0||p.y>=m)
return false;
else
return true;
}
int bfs(pair<int,int>a, pair<int,int>b, vector<vector<int>>& forest)
{
bool forestin[55][55];
memset(forestin, false, sizeof forestin);
if(forest[a.first][a.second]==0||forest[b.first][b.second]==0)
return -1;
if(a==b)
return 0;
int d[4][2] = {{0,-1},{0,1},{-1,0},{1,0}};
queue<Step> bfsqueue;
forestin[a.first][a.second] = true;
Step nexpos;
nexpos.x = a.first;
nexpos.y = a.second;
nexpos.s = 0;
bfsqueue.push(nexpos);
while(!bfsqueue.empty())
{
Step nowpos = bfsqueue.front();
//if(a==make_pair(3,1)&&b==make_pair(0,2))
//cout << nowpos.x << "^" << nowpos.y << "^" << nowpos.s << endl;
bfsqueue.pop();
for(int i=0;i<4;i++)
{
nexpos.x = nowpos.x + d[i][0];
nexpos.y = nowpos.y + d[i][1];
nexpos.s = nowpos.s + 1;
//if(a==make_pair(3,1)&&b==make_pair(0,2))
//cout << nexpos.x << "$" << nexpos.y << "$" << nexpos.s << endl;
if(legalPoint(nexpos)&&forest[nexpos.x][nexpos.y]>0&&(!forestin[nexpos.x][nexpos.y]))
{
forestin[nexpos.x][nexpos.y] = true;
if(nexpos.x==b.first&&nexpos.y==b.second)
return nexpos.s;
else
{
bfsqueue.push(nexpos);
//if(a==make_pair(3,1)&&b==make_pair(0,2))
//cout << nexpos.x << "#" << nexpos.y << "#" << nexpos.s << endl;
}
}
}
}
return -1;
}
};