【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中还看到几个大牛三位数的代码量 没琢磨懂 发上来大家一起研究学习

先是弱的代码

#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-12-27 20:14:45

【POJ 3083】Children of the Candy Corn的相关文章

POJ 3083:Children of the Candy Corn(DFS+BFS)

Children of the Candy Corn Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 9311 Accepted: 4039 Description The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and must wander through the maze facing zombies, ch

POJ 3083 Children of the Candy Corn(顺时针DFS+逆时针DFS+BFS)

题目链接:POJ 3083 Children of the Candy Corn [题意]给出一个迷宫,不超过40*40,'#'代表墙,'.'代表能走,'S'是起点,'E'是终点.分别求出从起点一直沿左走,一直沿右走,走到终点所需要的步数.以及走出迷宫的最小步数. [思路]首先最小步数很简单,一个普通BFS搞定,这道题重点是一直向左走和一直向右走的DFS的方向问题,方向还和游客当时朝向有关.开始一直认为是每次都向左(右)转,直到可以走,然后就一直不对,在google了之后才知道向左走要遵循左上右

POJ 3083 -- Children of the Candy Corn(DFS+BFS)TLE

POJ 3083 -- Children of the Candy Corn(DFS+BFS) 题意: 给定一个迷宫,S是起点,E是终点,#是墙不可走,.可以走 1)先输出左转优先时,从S到E的步数 2)再输出右转优先时,从S到E的步数 3)最后输出S到E的最短步数 解题思路: 前两问DFS,转向只要控制一下旋转方向就可以 首先设置前进方向对应的数字 向上--N--0 向右--E--1 向下--S--2 向左--W--3 比如说右转优先,即为向右,向前,向左,向后,即逆时针方向for(int i

POJ 3083 Children of the Candy Corn

Children of the Candy Corn Time Limit: 1000ms Memory Limit: 65536KB This problem will be judged on PKU. Original ID: 308364-bit integer IO format: %lld      Java class name: Main The cornfield maze is a popular Halloween treat. Visitors are shown the

POJ 3083 Children of the Candy Corn(搜索)

Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10975   Accepted: 4731 Description The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and must wander through the maze facing zombie

poj 3083 Children of the Candy Corn(bfs+dfs)

Children of the Candy Corn Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10739   Accepted: 4626 Description The cornfield maze is a popular Halloween treat. Visitors are shown the entrance and must wander through the maze facing zombie

【POJ 1408】 Fishnet (叉积求面积)

[POJ 1408] Fishnet (叉积求面积) 一个1*1㎡的池塘 有2*n条线代表渔网 问这些网中围出来的最大面积 一个有效面积是相邻两行和相邻两列中间夹的四边形 Input为n 后面跟着四行 每行n个浮点数 每一行分别代表a,b,c,d 如图 并且保证a(i) > a(i-1) b(i) > b(i-1) c(i) > c(i-1) d(i) > d(i-1) n(n <= 30)*2+4(四个岸)条边 枚举点数就行 相邻的四个四个点枚举 找出围出的最大面积 找点用

【POJ 2513】Colored Sticks

[POJ 2513]Colored Sticks 并查集+字典树+欧拉通路 第一次做这么混的题..太混了-- 不过题不算难 字典树用来查字符串对应图中的点 每个单词做一个点(包括重复单词 题意就是每个边走且直走一次(欧拉通路 欧拉图的判定: 没有或者只有两个奇数度的点的图叫做欧拉图 有这些就可以解答此题了 另外需要注意题目范围是25W个木棍 所以最多可能有50W个点 卡了好多个RE 代码如下: #include <iostream> #include <cstdlib> #incl

2292: 【POJ Challenge 】永远挑战

2292: [POJ Challenge ]永远挑战 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 553  Solved: 230[Submit][Status][Discuss] Description lqp18_31和1tthinking经常出题来虐ftiasch.有一天, lqp18_31搞了一个有向图,每条边的长度都是1. 他想让ftiasch求出点1到点 N 的最短路."水题啊.", ftiasch这么说道. 所以1tth