AtCoder Grand Contest 014C: Closed Rooms 题解

来源:互联网 发布:云计算平台技术 编辑:程序博客网 时间:2024/06/05 05:04

题目里面的每一组是先走K步再开k个锁

我们不妨换一下,先走<=k步,然后后面的每个组先开k个锁再走k步

我们可以发现开完再走,走完再开,每一组都一定能走k步

所以只要在地图里找从起点出发,走<=k步后距离边界最短的点

这个跑一个宽搜就可以了(注意不要跑dfs会tle的)

#include <cstdio>#include <iostream>#include <cstring>#include <string>#include <cmath>#include <algorithm>#include <cstdlib>#include <utility>#include <map>#include <stack>#include <set>#include <vector>#include <queue>#include <deque>#include <sstream>#include <bitset> #define x first#define y second#define mp make_pair#define pb push_back#define LL long long#define ld long double#define Pair pair<int,int>#define LOWBIT(x) x & (-x)using namespace std;const int INF=0x7ffffff;int ans=INF;int movee[5][3];bool visited[848][848];int r,c,k;int sx,sy;int a[848][848];char s[1000];queue<int> q;void bfs(int x,int y,int step){q.push(x);q.push(y);q.push(0);int cur_ans,cx,cy,cd,xx,yy,dd;visited[x][y]=true;while (!q.empty()){cx=q.front();q.pop();cy=q.front();q.pop();cd=q.front();q.pop();cur_ans=cx-1;cur_ans=min(cur_ans,cy-1);cur_ans=min(cur_ans,r-cx);cur_ans=min(cur_ans,c-cy);ans=min(ans,cur_ans);if (cd==k) continue;for (int i=1;i<=4;i++){xx=cx+movee[i][1];yy=cy+movee[i][2];if (xx<1 || xx>r || yy<1 || yy>c) continue;if (a[xx][yy]==1 || visited[xx][yy]) continue;visited[xx][yy]=true;q.push(xx);q.push(yy);q.push(cd+1);}}}int main (){int i,j;movee[1][1]=1;movee[1][2]=0;movee[2][1]=0;movee[2][2]=1;movee[3][1]=-1;movee[3][2]=0;movee[4][1]=0;movee[4][2]=-1;scanf("%d%d%d",&r,&c,&k);for (i=1;i<=r;i++){scanf("%s",s);for (j=1;j<=c;j++){if (s[j-1]=='#') a[i][j]=1;if (s[j-1]=='.') a[i][j]=2;if (s[j-1]=='S'){sx=i;sy=j;a[i][j]=2;}}}bfs(sx,sy,0);int fans=1+(ans+k-1)/k;printf("%d\n",fans);return 0;}

注意:宽搜要在搜到的一刹那把visited置成true,而不是在队列里面弹出的时候改

原创粉丝点击