[codeforces]Goodbye_2015

F. New Year and Cleaning

ime limit per test2 seconds
memory limit per test256 megabytes
inputstandard input
outputstandard output
Limak is a little polar bear. His parents told him to clean a house before the New Year’s Eve. Their house is a rectangular grid with h rows and w columns. Each cell is an empty square.

He is a little bear and thus he can’t clean a house by himself. Instead, he is going to use a cleaning robot.

A cleaning robot has a built-in pattern of n moves, defined by a string of the length n. A single move (character) moves a robot to one of four adjacent cells. Each character is one of the following four: ‘U’ (up), ‘D’ (down), ‘L’ (left), ‘R’ (right). One move takes one minute.

A cleaning robot must be placed and started in some cell. Then it repeats its pattern of moves till it hits a wall (one of four borders of a house). After hitting a wall it can be placed and used again.

Limak isn’t sure if placing a cleaning robot in one cell will be enough. Thus, he is going to start it w·h times, one time in each cell. Maybe some cells will be cleaned more than once but who cares?

Limak asks you one question. How much time will it take to clean a house? Find and print the number of minutes modulo 109 + 7. It’s also possible that a cleaning robot will never stop — then print “-1” (without the quotes) instead.

Placing and starting a robot takes no time, however, you must count a move when robot hits a wall. Take a look into samples for further clarification.

Input
The first line contains three integers n, h and w (1 ≤ n, h, w ≤ 500 000) — the length of the pattern, the number of rows and the number of columns, respectively.

The second line contains a string of length n — the pattern of n moves. Each character is one of uppercase letters ‘U’, ‘D’, ‘L’ or ‘R’.

Output
Print one line with the answer.

If a cleaning robot will never stop, print “-1” (without the quotes). Otherwise, print the number of minutes it will take to clean a house modulo 109 + 7.

Sample test(s)
input
1 10 2
R
output
30
input
3 4 6
RUL
output
134
input
4 1 500000
RLRL
output
-1
Note
In the first sample house is a grid with 10 rows and 2 columns. Starting a robot anywhere in the second column will result in only one move (thus, one minute of cleaning) in which robot will hit a wall — he tried to go right but there is no third column. Starting a robot anywhere in the first column will result in two moves. The total number of minutes is 10·1 + 10·2 = 30.

In the second sample a started robot will try to move “RULRULRULR…” For example, for the leftmost cell in the second row robot will make 5 moves before it stops because of hitting an upper wall.
题目大意:有机器人在矩形w*h中进行大扫除,按给定的指令进行循环走路,直到走向墙壁就停止,重新放置位置。机器人每次放置在不同的位置,进行w*h次清洗。计算其耗费的总时间,每个动作花费1分钟。
解题思路:先不管机器人在哪个位置开始,假设从(0,0)开始,用minx,miny,maxx,maxy记录它走过的最大边界。开始执行n条指令,每次更新minx或者maxx, w就减1,ans 加上 现在执行的动作次数乘以h,同样地, 每次更新miny或者maxy,h就减1,ans 加上 现在执行的动作次数乘以w,
直到h == 0或w==0退出
计算完第一次n条指令后,判断当前坐标是否为(0,0),是的话输出-1.
否则计算第二次n条指令,这次每更新minx,miny,maxx,maxy,都要将该指令存储下来。
可想而知第三次n条指令,每次更新minx,miny,maxx,maxy都会跟第二次执行的命令相同。直到h == 0或w==0退出
这时只需循环记录下来的更新minx,miny,maxx,maxy命令第k次命令结束则继续第k+1次直到h == 0或w==0结束

#include <cstdio>
#include <algorithm>
using namespace std;
typedef long long LL;
char s[500010];
int a[500010];
int c[500010];
const int module = 1e9 + 7;
int n, h, w;
int main() {
    scanf("%d%d%d", &n, &h, &w);
    scanf("%s", s);
    int minx = 0, miny = 0, maxx = 0, maxy = 0,flag = 0;
    int x = 0, y = 0;
    int ans = 0,  count = 0;
    long long  moves = 1;
    for (int i = 0; i < n; i++) {
        if (s[i] == 'L') {
            x--;
            if (minx > x) {
                ans = (ans+ moves * h % module) % module;
                w--;
                a[count++] = 1;
            }
            minx = min(x, minx);
        } else if (s[i] == 'R') {
            x++;
            if (maxx < x) {
                ans = (ans + moves * h % module) % module;
                w--;
                a[count++] = 2;
            }
            maxx = max(x, maxx);
        } else if (s[i] == 'U') {
            y++;
            if (maxy < y) {
                h--;
                ans = (ans + moves * w % module) % module;
                a[count++] = 3;
            }
            maxy = max(y, maxy);
        } else {
            y--;
            if (miny > y) {
                h--;
                ans = (ans + moves * w % module) % module;
                a[count++] = 4;
            }
            miny = min(y, miny);
        }
        if (w == 0 || h == 0) {
            flag = 1;
            break;
        }
        moves++;
    }
    if (x == 0 && y == 0 && !flag) {
        printf("-1\n");
    } else {
        count = 0;
        if (flag) { // 无判断是否已达到退出情况导致time limits
            printf("%d\n", ans);
            return 0;
        }
        for (int i = 0; i < n; i++) {
            if (s[i] == 'L') {
                x--;
                if (minx > x) {
                    ans = (ans+ moves * h % module) % module;
                    w--;
                    c[count] = moves%n;
                    a[count++] = 1;
                }
                minx = min(x, minx);
            } else if (s[i] == 'R') {
                x++;
                if (maxx < x) {
                    ans = (ans+ moves * h% module) % module;
                    w--;
                    c[count] = moves%n;
                    a[count++] = 2;
                }
                maxx = max(x, maxx);
            } else if (s[i] == 'U') {
                y++;
                if (maxy < y) {
                    h--;
                    ans = (ans + moves * w % module) % module;
                    c[count] = moves%n;
                    a[count++] = 3;
                }
                maxy = max(y, maxy);
            } else {
                y--;
                if (miny > y) {
                    h--;
                    ans = (ans + moves * w % module) % module;
                    c[count] = moves%n;
                    a[count++] = 4;
                }
                miny = min(y, miny);
            }
            if (count > 0 && c[count-1] % n == 0)
                c[count-1] = n;
            if (w == 0 || h == 0) { // 第二次循环时无判断是否已达到退出情况导致time limits
                flag = 1;
                break;
            }
            moves++;
        }
        if (flag) {
            printf("%d\n", ans);
            return 0;
        }
        int i = 0;
        long long k = 2;
        while (h != 0 && w != 0) {
            if (a[i] == 1) {
                w--;
                ans = (ans + (k * n % module + c[i]) * h % module)% module;
            } else if (a[i] == 2) {
                w--;
                ans = (ans + (k * n % module + c[i]) * h % module)% module;
            } else if (a[i] == 3) {
                h--;
                ans = (ans + (k * n % module + c[i]) * w % module)% module;
            } else {
                h--;
                ans = (ans + (k * n % module + c[i]) * w % module)% module;
            }
            if (i == count-1) {
                i = 0;
                k++;
            }
            else
                i++;
        }
        printf("%d\n", ans);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值