[USACO06JAN]树林The Grove
树木(grove)
Time Limit: 1Sec Memory Limit: 64 MB
【Description】
牧场里有一片树林,林子里没有坑.
贝茜很想知道,最少需要多少步能围绕树林走一圈,最后回到起点.她能上
下左右走,也能走对角线格子.牧场被分成R 行C 列(1≤R≤50,1≤C≤50).下
面是一张样例的地图,其中“.”表示贝茜可以走的空地, “X”表示树林, “*”
表示起点.而贝茜走的最近的路已经特别地用“+”表示出来.
...+...
..+X+..
.+XXX+.
..+XXX+
..+X..+
...+++*
题目保证,最短的路径一定可以找到.
【Input】
第1 行输入R 和C,接下来R 行C 列表示一张地图.地图中的符号如题
干所述.
【Output】、
输出最少的步数.
【Sample Input】
6 7
.......
...X...
..XXX..
...XXX.
...X...
......*
【Sample Output】
13
题解:
有一种很有意思的做法就是随便找一棵树向下沿出一条线,不能从右向左跨越这条线,如果从左向右跨越这条线的话就记为dis[1][x][y],那么只要是跨过了这条线就形成了一个环啦,最后的答案当然是dis[1][bx][by]
代码:
#include<cstdio> #include<cstring> #include<iostream> #include<queue> using namespace std; const int INF=1e9; const int cc[8][2]={{1,0},{-1,0},{0,-1},{0,1},{1,1},{-1,-1},{-1,1},{1,-1}}; int dis[2][55][55],bx,by,r,c,caty,catx;char st[55][55]; struct hh{int x,y,id;}; void bfs() { queue<hh>q; q.push((hh){bx,by,0}); memset(dis,0x7f,sizeof(dis)); dis[0][bx][by]=0; while (!q.empty()) { hh now=q.front(); q.pop(); for (int i=0;i<8;i++) { int xx=now.x+cc[i][0],yy=now.y+cc[i][1]; if (xx<1 || yy<1 || xx>r || yy>c || st[xx][yy]=='X') continue; if (yy==caty && now.y>caty && now.x>catx) continue; if (now.y==caty && yy>caty && now.x>catx) { if (dis[1][xx][yy]>dis[0][now.x][now.y]+1) { dis[1][xx][yy]=dis[0][now.x][now.y]+1; q.push((hh){xx,yy,1}); } } else { if (dis[now.id][xx][yy]>dis[now.id][now.x][now.y]+1) { dis[now.id][xx][yy]=dis[now.id][now.x][now.y]+1; q.push((hh){xx,yy,now.id}); } } } } printf("%d",dis[1][bx][by]); } int main() { int i,j; scanf("%d%d",&r,&c); bool vv=0; for (i=1;i<=r;i++) { scanf("%s",st[i]+1); for (j=1;j<=c;j++) { if (st[i][j]=='*') bx=i,by=j; if (st[i][j]=='X' && !vv) vv=1,caty=j,catx=i; } } bfs(); }
愿你走出半生,归来仍是少年