码迷,mamicode.com
首页 > 其他好文 > 详细

【POJ 3083】Children of the Candy Corn

时间:2015-06-15 09:13:29      阅读:120      评论:0      收藏:0      [点我收藏+]

标签:dfs   bfs      

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;
}

【POJ 3083】Children of the Candy Corn

标签:dfs   bfs      

原文地址:http://blog.csdn.net/challengerrumble/article/details/46497977

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!