【POJ 3083】Children of the Candy Corn

POJ【3083】Children of the Candy Corn

Dfs+Bfs 分别求沿左墙到达E 沿右墙到达E 还有S到E的最短步数 前两个Dfs实现 最后一个Bfs 耐心写很容易A

主要注意方向问题 dir四个方向 上右下左 刚开始我分别用下标0 1 2 3代表 开dirx diry两个移动数组 假设前一状态朝向0(上) 沿左墙移动即为3 0 1 2(左上右下<顺时针>) 沿右墙即为1 0 3 2(右上左下<逆时针>) 同理其余方向很容易遍历

略自豪的是不断精简代码从6000多B到了2000多

主要是把Dfs遍历时的方向判断和for循环给精简了 把两个数组开成上右下左上右下 这样对于所有方向都能用一个for遍历完 代码量缩短很多

在discussion中还看到几个大牛三位数的代码量 没琢磨懂 发上来大家一起研究学习

先是弱的代码

;char mp[44][44];int w,h;pair <int,int> st,en;bool vis[44][44];int dis[44][44];int dirx[] = {-1, 0, 1, 0,-1, 0, 1};int diry[] = { 0, 1, 0,-1, 0, 1, 0};bool Dfsl(int x,int y,int dir){if(x == en.first && y == en.second) return 1;int i,xx,yy;for(i = (dir+3)%4; i < (dir+3)%4+4; ++i){xx = x + dirx[i];yy = y + diry[i];if(xx > 0 && yy > 0 && xx <= h && yy <= w && mp[xx][yy] != ‘#’){dis[xx][yy] = dis[x][y] + 1;if(Dfsl(xx,yy,i)) return 1;}}return 0;}bool Dfsr(int x,int y,int dir){if(x == en.first && y == en.second) return 1;int i,xx,yy;for(i = (dir+2)%4+3; i >= (dir+2)%4; –i){xx = x + dirx[i];yy = y + diry[i];if(xx > 0 && yy > 0 && xx <= h && yy <= w && mp[xx][yy] != ‘#’){dis[xx][yy] = dis[x][y] + 1;if(Dfsr(xx,yy,i)) return 1;}}return 0;}void Bfs(){memset(vis,0,sizeof(vis));queue<pair<int,int> > q;q.push(st);vis[st.first][st.second] = 1;int x,y,xx,yy,i;while(!q.empty()){x = q.front().first;y = q.front().second;q.pop();for(i = 0; i < 4; ++i){xx = x + dirx[i];yy = y + diry[i];if(xx > 0 && yy > 0 && xx <= h && yy <= w && !vis[xx][yy] && mp[xx][yy] != ‘#’){dis[xx][yy] = dis[x][y] + 1;vis[xx][yy] = 1;if(xx == en.first && yy == en.second) return;q.push(pair<int,int> (xx,yy));}}}}int main(){int t,i,j;scanf(“%d”,&t);while(t–){scanf(“%d %d”,&w,&h);for(i = 1; i <= h; ++i){scanf(“%s”,mp[i]+1);for(j = 1; j <= w; ++j){if(mp[i][j] == ‘S’){st.first = i;st.second = j;}else if(mp[i][j] == ‘E’){en.first = i;en.second = j;}}}dis[st.first][st.second] = 1;Dfsl(st.first,st.second,0);printf(“%d “,dis[en.first][en.second]);Dfsr(st.first,st.second,0);printf(“%d “,dis[en.first][en.second]);Bfs();printf(“%d\n”,dis[en.first][en.second]);}return 0;}

思维帝Orz代码

char map[M][M];int w, h, sr, sc, er, ec, dr[4] = {0, 1, 0, -1}, dc[4] = {1, 0, -1, 0};void gao(int d, int t) {int r = sr, c = sc, s = 1;while(r != er || c != ec) {d = d + 4 – t;while(map[r+dr[d%4]][c+dc[d%4]] == ‘#’) d += t;r += dr[d%4], c += dc[d%4], s++;}printf(“%d “, s);}int valid(int r, int c) {return (r >= 0 && r < h && c >= 0 && c < w);}void bfs() {int qr[M*M], qc[M*M], v[M][M], d[M][M], h = 0, t = 0, r, c, x, y, i;memset(v, 0, sizeof(v));qr[t] = sr, qc[t] = sc, t++, v[sr][sc] = d[sr][sc] = 1;while(h < t) {r = qr[h], c = qc[h], h++;if(r == er && c == ec) {printf(“%d\n”, d[r][c]);break;}for(i = 0; i < 4; i++)if(valid(x=r+dr[i], y=c+dc[i]) && map[x][y] == ‘.’ && !v[x][y])qr[t] = x, qc[t] = y, t++, v[x][y] = 1, d[x][y] = d[r][c] + 1;}}int main() {int T, i, j, d;scanf(“%d”, &T);while(T–) {scanf(“%d%d”, &w, &h);for(i = 0; i < h; i++) {scanf(“%s”, map[i]);for(j = 0; j < w; j++)if(map[i][j] == ‘S’)sr = i, sc = j;else if(map[i][j] == ‘E’)er = i, ec = j, map[i][j] = ‘.’;}if(sc == 0) d = 0;if(sr == 0) d = 1;if(sc == w – 1) d = 2;if(sr == h – 1) d = 3;gao(d, 1);gao(d, -1);bfs();}}也许不是自己该去发挥的地方,还是让自己到最适合自己战斗的方面去吧!勇敢的接受自己的失败,

【POJ 3083】Children of the Candy Corn

相关文章:

你感兴趣的文章:

标签云: