Codeforces 589J Cleaner Robot(DFS)

Cleaner Robot

Time Limit: 2000MS   Memory Limit: 524288KB   64bit IO Format: %I64d & %I64u

Submit Status

Description

Masha has recently bought a cleaner robot, it can clean a floor without anybody‘s assistance.

Schematically Masha‘s room is a rectangle, consisting of w × h square cells of size 1 × 1. Each cell of the room is either empty (represented by character ‘.‘), or occupied by furniture (represented by character ‘*‘).

A cleaner robot fully occupies one free cell. Also the robot has a current direction (one of four options), we will say that it looks in this direction.

The algorithm for the robot to move and clean the floor in the room is as follows:

  1. clean the current cell which a cleaner robot is in;
  2. if the side-adjacent cell in the direction where the robot is looking exists and is empty, move to it and go to step 1;
  3. otherwise turn 90 degrees clockwise (to the right relative to its current direction) and move to step 2.

The cleaner robot will follow this algorithm until Masha switches it off.

You know the position of furniture in Masha‘s room, the initial position and the direction of the cleaner robot. Can you calculate the total area of the room that the robot will clean if it works infinitely?

Input

The first line of the input contains two integers, w and h(1 ≤ w, h ≤ 10) — the sizes of Masha‘s room.

Next w lines contain h characters each — the description of the room. If a cell of a room is empty, then the corresponding character equals ‘.‘. If a cell of a room is occupied by furniture, then the corresponding character equals ‘*‘. If a cell has the robot, then it is empty, and the corresponding character in the input equals ‘U‘, ‘R‘, ‘D‘ or ‘L‘, where the letter represents the direction of the cleaner robot. Letter ‘U‘ shows that the robot is looking up according to the scheme of the room, letter ‘R‘ means it is looking to the right, letter ‘D‘ means it is looking down and letter ‘L‘ means it is looking to the left.

It is guaranteed that in the given w lines letter ‘U‘, ‘R‘, ‘D‘ or ‘L‘ occurs exactly once. The cell where the robot initially stands is empty (doesn‘t have any furniture).

Output

In the first line of the output print a single integer — the total area of the room that the robot will clean if it works infinitely.

Sample Input

Input

2 3U...*.

Output

4

Input

4 4R....**..**.....

Output

12

Input

3 4***D..*.*...

Output

6

Hint

In the first sample the robot first tries to move upwards, it can‘t do it, so it turns right. Then it makes two steps to the right, meets a wall and turns downwards. It moves down, unfortunately tries moving left and locks itself moving from cell (1, 3) to cell (2, 3) and back. The cells visited by the robot are marked gray on the picture.

Source

2015-2016 ACM-ICPC, NEERC, Southern Subregional Contest (Online Mirror, ACM-ICPC Rules, Teams Preferred)

解法一:

//英文题,看错了题。。。

//深搜,记录第一次经过某点的方向,此后再经过此点时,判断和初次的方向是否一致,如果一致,说明陷入了重复,不必继续搜索
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <set>
#include <stack>
#include <vector>
#include <algorithm>
using namespace std;

char s[20][20];
int n, m, cnt;
int dx[] = {0, -1, 0, 1, 0}, dy[] = {0, 0, 1, 0, -1}; //控制方向
bool use[20][20]; //标记是否经过
int dirr[20][20]; //记录第一次经过某点时的方向
void dfs(int x, int y, int dir)
{
    if(use[x][y] == false) //第一次经过此点,加一,记录方向
    {
        cnt++;
        dirr[x][y] = dir;
    }
    use[x][y] = true;

    int nx, ny, dir1;
    for(int i = 0; i < 4; i++) //顺时针旋转,只要碰到点就进入下一层,然后不能再继续顺时针旋转
    {
        dir1 = (dir + i) % 4;
        if(dir1 == 0) dir1 = 4;
        nx = x + dx[dir1], ny = y + dy[dir1];
        if(nx >= 0 && nx < n && ny >= 0 && ny < m && s[nx][ny] == ‘.‘)
        {
            if(dirr[nx][ny] == dir1) break;
            dfs(nx, ny, dir1);
            break;
        }
    }
}

int main()
{
    int x, y;
    while(~ scanf("%d%d", &n, &m))
    {
        int dir;
        cnt = 0;
        memset(use, false, sizeof use);
        for(int i = 0; i < n; i++)
            for(int j = 0; j < m; j++)
            {
                scanf(" %c", &s[i][j]);
                if(s[i][j] == ‘U‘) x = i, y = j, dir = 1, s[i][j] = ‘.‘;
                else if(s[i][j] == ‘R‘) x = i, y = j, dir = 2, s[i][j] = ‘.‘;
                else if(s[i][j] == ‘D‘) x = i, y = j, dir = 3, s[i][j] = ‘.‘;
                else if(s[i][j] == ‘L‘) x = i, y = j, dir = 4, s[i][j] = ‘.‘;
            }
        dfs(x, y, dir);
        printf("%d\n", cnt);
    }

    return 0;
}

解法二:

#include<stdio.h>
#include<string.h>

const int MAXN = 17;

 ///‘U‘, ‘R‘, ‘D‘ ‘L‘
int dir[4][2] = { {-1,0},{0,1},{1,0},{0,-1} };
int M, N;
char G[MAXN][MAXN];
bool v[MAXN][MAXN][4];

void DFS(int k, int x, int y, int &ans)
{
    if(G[x][y] == ‘.‘)
    {
        ans += 1;
        G[x][y] = ‘#‘;
    }

    for(int i=0; i<4; i++)
    {
        int nx = x+dir[(i+k)%4][0];
        int ny = y+dir[(i+k)%4][1];

        if(nx>=0&&nx<M && ny>=0&&ny<N && G[nx][ny]!=‘*‘)
        {
            if(v[nx][ny][(i+k)%4] == true)
                break;
            v[nx][ny][(i+k)%4] = true;
            DFS((i+k)%4, nx, ny, ans);
            break;
        }
    }
}

int main()
{
    while(scanf("%d%d", &M, &N) != EOF)
    {
        memset(v, 0, sizeof(v));

        int x, y, op;

        for(int i=0; i<M; i++)
        {
            scanf("%s", G[i]);
            for(int j=0; j<N; j++)
            {
                if(G[i][j] == ‘U‘)
                    op = 0, x=i, y=j;
                if(G[i][j] == ‘R‘)
                    op = 1, x=i, y=j;
                if(G[i][j] == ‘D‘)
                    op = 2, x=i, y=j;
                if(G[i][j] == ‘L‘)
                    op = 3, x=i, y=j;
            }
        }

        int ans = 1;
        DFS(op, x, y, ans);

        printf("%d\n", ans);
    }

    return 0;
}
时间: 2024-10-27 03:16:30

Codeforces 589J Cleaner Robot(DFS)的相关文章

CodeForces 589J Cleaner Robot (DFS,或BFS)

题意:给定n*m的矩阵,一个机器人从一个位置,开始走,如果碰到*或者边界,就顺时针旋转,接着走,问你最后机器人最多能走过多少格子. 析:这个题主要是题意读的不大好,WA了好几次,首先是在*或者边界才能转向,其次就是走过的地方也能走,注意这两点,就可以AC了,可以用DFS,也可以用BFS, 我用的DFS. 代码如下: #pragma comment(linker, "/STACK:1024000000,1024000000") #include <cstdio> #inclu

CodeForces 589J Cleaner Robot

有一个M*N的矩阵,有一个会自动清洁的机器人,这个机器人会按照设定好的程序来打扫卫生,如果当前方向前面可以行走,那么直接走,如果不可以走那么会向右转动90度,然后回归上一步判断.求机器人最多能打扫的面积是多少 一开始认为是走到之前清扫过的就停止搜索 后来知道是走到一个四个方向都走过的点才停止搜索 #include<stdio.h> #include<string.h> const int MAXN = 17; ///'U', 'R', 'D' 'L' int dir[4][2] =

CodeForce 589J Cleaner Robot

Cleaner Robot Masha has recently bought a cleaner robot, it can clean a floor without anybody's assistance. Schematically Masha's room is a rectangle, consisting of w × h square cells of size 1 × 1. Each cell of the room is either empty (represented

Codeforces 583 DIV2 Robot&#39;s Task 贪心

原题链接:http://codeforces.com/problemset/problem/583/B 题意: 就..要打开一个电脑,必须至少先打开其他若干电脑,每次转向有个花费,让你设计一个序列,使得总花费最小. 题解: 就傻傻的走就好..从左走到右,再走回来,更新序列和答案就好. 代码: #include<iostream> #include<cstring> #include<algorithm> #include<cstdio> #define MA

Codeforces 384E 线段树+dfs序

题目链接:点击打开链接 题意: 给定n个点,m个询问的无向树(1为根) 下面n个数表示每个点的权值 下面n-1行给出树 操作1:x点权值+v, x的第 i & 1 的儿子-v, 第 !(i&1) 的儿子+v 操作2:询问x点权值 dfs把树转成序列 根据深度把点分成2组 分别用线段树维护.. 然后Y一下 #include<stdio.h> #include<string.h> #include<iostream> #include<algorith

Cleaner Robot - CodeForces 589J(搜索)

有一个M*N的矩阵,有一个会自动清洁的机器人,这个机器人会按照设定好的程序来打扫卫生,如果当前方向前面可以行走,那么直接走,如果不可以走那么会向右转动90度,然后回归上一步判断.求机器人最多能打扫的面积是多少. 分析:直接搜就行了....... 代码如下: ---------------------------------------------------------------------------------------------------------------- #include

【Codeforces 922D】Robot Vacuum Cleaner

[链接] 我是链接,点我呀:) [题意] 让你把n个字符串重新排序,然后按顺序连接在一起 使得这个组成的字符串的"sh"子序列最多 [题解] /* * 假设A的情况好于B * 也就对应了A排在B的前面 * 那么 * As*Bh>Ah*Bs ① * 现在假设B又比C来得好 * 那么有 * Bs*Ch>Bh*Cs ② * 由①可得 * As/Ah>Bs/Bh * 由②可得 * Bs/Bh>Cs/Ch * 那么有 * As/Ah>As/Ch * 即As*Ch&g

Codeforces Gym 100463D Evil DFS

Evil Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100463/attachments Description Richard is evil. He wants to give another geometry problem to the participants of this contest and I’m afraid I have no choice but to comply. W

Codeforces 466E Information Graph(dfs+并查集)

题目链接:Codeforces 466E Information Graph 题目大意:一开始有n个员工,他们互相独立.现在有三种操作. 1 u v,v称为u的上级 2 u,从u发起一份文件,逐层递交给上级 3 u v,询问u是否查阅过v号文件. 解题思路:将每个文件移动的范围处理出来,然后对于每次询问,将询问拆成两个标记,假设查询x是否浏览过第k号文件,第k号文件的范围为u-v,那么在最后dfs时,遍历到x,判断是否经过u:遍历到v时,判断是否经过x.如果两个都满足,则是YES. #inclu