USACO的题目,感觉还是挺神奇的.
前置芝士
1.DFS(BFS)遍历:用来搜索(因为DFS好写,本文以DFS为准还不是因为作者懒)
2.STL中的set(map)的基本用法:数据很大,不能直接存.具体做法
因为不能把草堆围起来造成的周长记录起来所以不能再草堆中搜索,需要再这个草堆外面绕着搜索这样就不会将内部的周长记录下来了.
如这样一张图它的周长是(红色部分):
于是需要找到一个在最外边的点,可以发现最上方的那个点的就十分合适,搜索的位置(蓝色部分)
从最上方开始搜,如果搜到了草就answer++,return.
但是这样搜的时候如果一直往外跑就会直接炸掉,所以必须不能有这种情况,可以发现对于每一个蓝色位置的八个方向的一格处至少有一个草堆,于是如果没有草堆就直接退出.代码
#include<bits/stdc++.h> #define rap(i,first,last) for(int i=first;i<=last;++i) using namespace std; const int move_x[9]={233,0,0,1,-1,1,1,-1,-1}; const int move_y[9]={233,1,-1,0,0,1,-1,1,-1}; set<pair<int,int> >_map;//用来记录这张图 set<pair<int,int> >visit;//用来判断这个位置有没有走过 int N,fx=-1,fy,answer=0; bool OutSide(int x,int y)//判断八个方向上有没有草堆 { rap(i,1,8) if(_map.count(make_pair(x+move_x[i],y+move_y[i])))return 0;//有就返回0 return 1;//没有返回1 } void DFS(int x,int y)//DFS { if(_map.count(make_pair(x,y)))//如果这个位置是草堆就answer++,return { answer++; return; } if(visit.count(make_pair(x,y)))return;//走过了就不能在走了 visit.insert(make_pair(x,y));//记录这个位置走过 if(OutSide(x,y))return;//如果八个方向上没有草堆则return rap(i,1,4)//向四个方向搜索 DFS(x+move_x[i],y+move_y[i]); } int main() { scanf("%d",&N); int x,y; rap(i,1,N) { scanf("%d%d",&x,&y); _map.insert(make_pair(x,y));//地图中这个位置有草堆 if(x>fx) { fx=x; fy=y; } } DFS(fx+1,fy);//最上方那个点上方的那个点开始搜索 printf("%d",answer);//输出answer return 0; }
来源:https://www.cnblogs.com/Sxy_Limit/p/12166883.html