ZOJ4093题解(Robot Cleaner II)

Robot Cleaner II

题目链接:ZOJ 4093

Robot Cleaner II

Time Limit: 1 Second
Memory Limit: 65536 KB
Special Judge

(Please read the description of Robot Cleaner I first.)
Tired of programming the robot every time according to the situation of his room, BaoBao decides to write a “super program” so that the robot can pick up most of the litter using this program, no matter how the litter is positioned in the room.

To simplify this problem, we now put some constraints on BaoBao’s room and the robot.

  • n = m = 12
  • For all 1
  • There are exactly 50 pieces of litter in the room, and they are randomly distributed with equal probability;
  • The robot always starts from (2, 2).

Your task is to design the “super program”, so that when feeding this program to the controller, the robot can pick up at least 95% of the litter in the room under the above constraints after executing 200 instructions.

Input
There is no input for this problem.

Output
You should output a string of length 243 ( 243 = 3 5 243 = 3^5 243=35) consisting of ‘U’, ‘D’, ‘L’, ‘R’, ‘P’ and ‘I’ in one line, indicating your super program.

题意

这一题前置题是Robot Cleaner I,对于I没什么好说的,直接暴力模拟即可。II在I的基础上,让设计一个长度为243的操作串,对于任意随机的12*12的地图,机器人从左上角开始操作,在200次操作内都能捡到绝大多数垃圾。判题机随机生成多个地图,要求对所有地图按照操作串进行200次操作,捡的垃圾/总垃圾数平均在95%以上

题解

这一题嘛,主要是贪心+玄学AC
因为题目地图不给出,要求的输出的操作串对于随机出现的数据都能捡到绝大多数垃圾,那么我们给定以下几个假设:

  • 当所处位置有垃圾,那么下一步操作一定是捡垃圾’P’。因为操作数有限,要捡绝大多数垃圾,那么按照贪心的策略,看到垃圾就捡,如果不捡垃圾,就等于是这个垃圾下次还要回到这个格子再捡,浪费了操作数。
  • 当所处位置没有垃圾,那么下一步必然向上下左右四个方向的某个方向前进一格,这时选择方向就成问题了,这时依然选择贪心策略。
    1. 先处理出地图边缘的格子走法,按照顺时针或者逆时针方向走,这样就尽可能地防止两个格子之间来回跑
    2. 当某个相邻格子有垃圾,并且其他相邻格子没有垃圾,那么就向有垃圾的方向移动一格
    3. 当多个相邻格子有垃圾,那么就需要考虑一个优先级的问题了,而由于整个图是随机的,所以优先级顺序构成环应该是比较优的。比如上 > 下 > 左 > 右 > 上,这样的应该是比上 > 下 > 左 > 右要更好。后一种策略只要上方有垃圾就向上走,就很容易碰壁然后就卡死了,而前一种策略就不那么容易卡死
    4. 第2步和第3步的策略可能会覆盖掉第1步的策略,否则就会一直在外围转圈圈
    5. 当4个方向全是垃圾或者全没有垃圾的时候,选择某个固定方向(右和下应该是比左和上要优的,毕竟起始点在左上角)
    6. 当然,卡死以上贪心策略的图也是很容易拼凑出来的,但随机出那种图就不那么容易了。

代码

#include 
using namespace std;

char s[255];
// 当机器人机器人所在格子为0,根据上下左右的格子情况得到在操作串中对应的位置
inline int get(int a, int b, int c, int d)
{
    return a*27 + b*9 + c*3 + d;
}

int main()
{
    for(int i = 0; i < 243; ++ i)
        s[i] = 'P';
    s[243] = 0;

    for(int a = 0; a < 3; ++ a)
        for(int b = 0; b < 3; ++ b)
            for(int c = 0; c < 3; ++ c)
                for(int d = 0; d < 3; ++ d)
                {
                    int t = get(a, b, c, d);
                    if(a == 1 && d != 1)
                        s[t] = 'R';
                    if(d == 1 && b != 1)
                        s[t] = 'D';
                    if(b == 1 && c != 1)
                        s[t] = 'L';
                    if(c == 1 && a != 1)
                        s[t] = 'U';
                }

    for(int i = 0; i < 81; ++ i)
    {
        int u = i / 27;
        int d = i % 27 / 9;
        int l = i % 9 / 3;
        int r = i % 3;

        if(u == 2 && d != 2)
            s[i] = 'U';
        else if(d == 2 && l != 2)
            s[i] = 'D';
        else if(l == 2 && r != 2)
            s[i] = 'L';
        else if(r == 2)
            s[i] = 'R';
    }
    s[0] = 'R';

    printf("%s\n", s);

    return 0;
}

你可能感兴趣的:(ACM)