HDU 2782 The Worm Turns (DFS)

Winston the Worm just woke up in a fresh rectangular patch of earth. The rectangular patch is divided into cells, and each cell contains either food or a rock. Winston wanders aimlessly for a while until he gets hungry; then he immediately eats the food in his cell, chooses one of the four directions (north, south, east, or west) and crawls in a straight line for as long as he can see food in the cell in front of him. If he sees a rock directly ahead of him, or sees a cell where he has already eaten the food, or sees an edge of the rectangular patch, he turns left or right and once again travels as far as he can in a straight line, eating food. He never revisits a cell. After some time he reaches a point where he can go no further so Winston stops, burps and takes a nap.

For instance, suppose Winston wakes up in the following patch of earth (X‘s represent stones, all other cells contain food):

If Winston starts eating in row 0, column 3, he might pursue the following path (numbers represent order of visitation):

In this case, he chose his path very wisely: every piece of food
got eaten. Your task is to help Winston determine where he should begin
eating so that his path will visit as many food cells as possible.

InputInput will consist of multiple test cases.
Each test case begins with two positive integers, m and n , defining the
number of rows and columns of the patch of earth. Rows and columns are
numbered starting at 0, as in the figures above. Following these is a
non-negative integer r indicating the number of rocks, followed by a
list of 2r integers denoting the row and column number of each rock. The
last test case is followed by a pair of zeros. This should not be
processed. The value m×n will not exceed 625.OutputFor each test case, print the test case number (beginning with 1), followed by four values:

amount row column direction

where amount is the maximum number of pieces of food that Winston is
able to eat, (row, column) is the starting location of a path that
enables Winston to consume this much food, and direction is one of E, N,
S, W, indicating the initial direction in which Winston starts to move
along this path. If there is more than one starting location, choose the
one that is lexicographically least in terms of row and column numbers.
If there are optimal paths with the same starting location and
different starting directions, choose the first valid one in the list E,
N, S, W. Assume there is always at least one piece of food adjacent to
Winston‘s initial position.Sample Input

5 5
3
0 4 3 1 3 2
0 0

Sample Output

Case 1: 22 0 3 W分析题目大意就是给你一个地图,地图中只有两种元素,墙跟平地,然后要你求出一个人能在这个地图中走的最大距离。这个人一旦开始走路,那么他走的方向将是不变的。除非遇到墙,或者遇到地图的边,亦或者那个格子已经走过了,这个时候这个人才开始更换方向。然后要你求出这个人能走的最大距离的起始点的位置,输出最大距离,起始点坐标,还有一开始走的方向。(E,N,S,W),如果最大距离相同,那么要输出起始点坐标的字典序最小的那个。还有,如果四个方向都能达到最大,那么选择的方向的优先级由(E,N,S,W)往下排列。 就是爆搜,题目给的时间很大。我们可以枚举起点,对于每一个点搜索。关于输出,在搜索时按(E,N,S,W)的顺序,在更新答案时,只有当前答案大于记录答案才更新。
#include <cstdio>
#include <iostream>
#include <cmath>
#include <queue>
#include <algorithm>
#include <cstring>
#include <climits>
#define MAXN 626
#define X rx+dx[i]
#define Y ry+dy[i]
using namespace std;
int t=0;
int r,m,n,g[MAXN][MAXN],ans[MAXN][MAXN],sx,sy,step,ansdd,ansx,ansy,md,maxx;
int ansd[MAXN][MAXN];
int dx[5]={0,0,-1,1,0},
        dy[5]={0,1,0,0,-1};
void dfs(int x,int y)
{
    for(int i=1;i<=4;i++)
    {
        int rx=x,ry=y;
        if(X>=0&&X<n&&Y>=0&&Y<m&&g[X][Y]==0)
        {
            if(x==sx&&y==sy) md=i;
            g[X][Y]=++step;
            if(step>ans[sx][sy])
                ans[sx][sy]=step,
                ansd[sx][sy]=md;
            rx+=dx[i];ry+=dy[i];
            while(X>=0&&X<n&&Y>=0&&Y<m&&g[X][Y]==0)
            {
                g[X][Y]=++step;
                if(step>ans[sx][sy])
                    ans[sx][sy]=step,
                    ansd[sx][sy]=md;
                rx+=dx[i];ry+=dy[i];
            }
            dfs(rx,ry);
            while(rx!=x||ry!=y)
            {
                g[rx][ry]=0;
                step--;
                rx-=dx[i];ry-=dy[i];
            }
        }
    }
}
void init()
{
    memset(g,0,sizeof(g));
    memset(ans,0,sizeof(ans));
    memset(ansd,0,sizeof(ansd));
    ansdd=ansx=ansy=md=maxx=0;
}
int main()
{
//    freopen("1.in","r",stdin);
//    freopen("1.out","w",stdout);
    while(1)
    {
        init();
        ++t;
        scanf("%d%d",&n,&m);
        if(n==0&&m==0)return 0;
        scanf("%d",&r);
        for(int i=1;i<=r;i++)
        {
            int x,y;
            scanf("%d%d",&x,&y);
            g[x][y]=-1;
        }
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(g[i][j]!=-1)
                {
                    step=0;sx=i;sy=j;
                    g[sx][sy]=-1;
                    dfs(sx,sy);
                    g[sx][sy]=0;
                }
        for(int i=0;i<n;i++)
            for(int j=0;j<m;j++)
                if(ans[i][j]>maxx)
                {
                    maxx=ans[i][j];
                    ansx=i;ansy=j;
                    ansdd=ansd[i][j];
                }
        printf("Case %d: %d %d %d ",t,maxx+1,ansx,ansy);
        if(ansdd==1) printf("E\n");
        else if(ansdd==2) printf("N\n");
        else if(ansdd==3) printf("S\n");
        else if(ansdd==4) printf("W\n");
    }
    return 0;
}
时间: 2024-09-28 00:13:40

HDU 2782 The Worm Turns (DFS)的相关文章

The Worm Turns

The Worm Turns Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 106 Accepted Submission(s): 54   Problem Description Winston the Worm just woke up in a fresh rectangular patch of earth. The rectang

HDU 哈密顿绕行世界问题 (dfs)

Problem Description 一个规则的实心十二面体,它的 20个顶点标出世界著名的20个城市,你从一个城市出发经过每个城市刚好一次后回到出发的城市. Input 前20行的第i行有3个数,表示与第i个城市相邻的3个城市.第20行以后每行有1个数m,m<=20,m>=1.m=0退出. Output 输出从第m个城市出发经过每个城市1次又回到m的所有路线,如有多条路线,按字典序输出,每行1条路线.每行首先输出是第几条路线.然后个一个: 后列出经过的城市.参看Sample output

HDU 1241 Oil Deposits --- 入门DFS

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=1241 /* HDU 1241 Oil Deposits --- 入门DFS */ #include <cstdio> int m, n; //n行m列 char mapp[105][105]; /* 将和i,j同处于一个连通块的字符标记出来 */ void dfs(int i, int j){ if (i < 0 || j < 0 || i >= n || j >= m

hdu 2489 Minimal Ratio Tree(dfs枚举 + 最小生成树)~~~

题目: 链接:点击打开链接 题意: 输入n个点,要求选m个点满足连接m个点的m-1条边权值和sum与点的权值和ans使得sum/ans最小,并输出所选的m个点,如果有多种情况就选第一个点最小的,如果第一个点也相同就选第二个点最小的........ 思路: 求一个图中的一颗子树,使得Sum(edge weight)/Sum(point weight)最小~ 数据量小,暴力枚举~~~~~dfs暴力枚举C(M,N)种情况. 枚举出这M个点之后,Sum(point weight)固定,进行prim或者K

HDU 1010 Tempter of Bone DFS + 奇偶剪枝

奇偶剪枝: 对于从起始点 s 到达 终点 e,走且只走 t 步的可达性问题的一种剪枝策略. 如下列矩阵 : 从任意 0 到达 任意 0,所需步数均为偶数,到达任意 1 ,均为奇数.反之亦然 所以有,若s走且只走 t 步可到达e,则必有t >= abs(s.x - e.x) + abs(s.y - e.y),且 (t&1) == ((abs(s.x - e.x) + abs(s.y - e.y))&1). 否则必不可达. #include <iostream> #inclu

HDU 1501 Zipper(DP,DFS)

题意  判断能否由字符串a,b中的字符不改变各自的相对顺序组合得到字符串c 本题有两种解法  DP或者DFS 考虑DP  令d[i][j]表示能否有a的前i个字符和b的前j个字符组合得到c的前i+j个字符  值为0或者1  那么有d[i][j]=(d[i-1][j]&&a[i]==c[i+j])||(d[i][j-1]&&b[i]==c[i+j])   a,b的下标都是从1开始的  注意0的初始化 #include<cstdio> #include<cst

HDU 1180 诡异的楼梯 (DFS)

诡异的楼梯 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65536 K (Java/Others) Total Submission(s): 6472    Accepted Submission(s): 1525 Problem Description Hogwarts正式开学以后,Harry发现在Hogwarts里,某些楼梯并不是静止不动的,相反,他们每隔一分钟就变动一次方向. 比如下面的例子里,一开始楼梯在竖

hdu 1241 Oil Deposits(DFS求连通块)

HDU 1241  Oil Deposits L -DFS Time Limit:1000MS     Memory Limit:10000KB     64bit IO Format:%I64d & %I64u Description The GeoSurvComp geologic survey company is responsible for detecting underground oil deposits. GeoSurvComp works with one large rec

HDU 1484 Basic wall maze (dfs + 记忆化)

Basic wall maze Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 168    Accepted Submission(s): 52 Special Judge Problem Description In this problem you have to solve a very simple maze consisti