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中还看到几个大牛三位数的代码量 没琢磨懂 发上来大家一起研究学习
先是弱的代码
#include <cstdio>
#include <cstring>
#include <queue>
using namespace std;
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代码
#include <cstdio>
#include <cstring>
#define M 45
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();
}
}
PS:简化代码原来也会上瘾。。。。再来一发(虽然没少多少
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;
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};
int Dfs(int x,int y,int s,int ad)
{
if(x == en.first && y == en.second) return dis[x][y];
int i,xx,yy,f = 0;
for(i = s; abs(i-s) < 4; i += ad)
{
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(ad == 1) f = Dfs(xx,yy,(i+3)%4,1);
else f = Dfs(xx,yy,(i+2)%4+3,-1);
if(f) return f;
}
}
return 0;
}
int 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 dis[xx][yy];
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;
printf("%d %d %d\n",Dfs(st.first,st.second,3,1),Dfs(st.first,st.second,3,-1),Bfs());
}
return 0;
}
时间: 2024-10-26 16:27:23