POJ2632Crashing Robots

本文介绍了一款用于模拟机器人在二维网格中行走的程序。该程序通过解析指令来控制机器人移动,同时检测机器人间的碰撞及与边界的碰撞。文章详细解释了如何使用整数模4来简化方向的转换,并分享了一些调试经验。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一个方阵,横纵坐标从1开始编制,方向如图。几个机器车在方阵内分别走,走的命令如下。一个机器人一条命令执行完之后才执行第二条命令。

An instruction has the following format: 
< robot #> < action> < repeat> 
Where is one of 
L: turn left 90 degrees, 
R: turn right 90 degrees, or 
F: move forward one meter,

题目示意

冲突的条件有两个

  1. 撞墙,A robot crashes into a wall if Xi = 0, Xi = A + 1, Yi = 0 or Yi = B + 1.
  2. 已经有人站坑里了

一遍过的题目,但调bug用的时间比较久,关键在与break跳出循环一定要看看被省略的循环里有没有输入,如果有不能直接break,需要把循环走完,主要因为这个问题,导致第二次测试开始的输入有问题。

另外方向用整数表示,并模4的方法方便多次转向。如下代码所示。

robot[rbt].drct = (robot[rbt].drct - 1 + 4)%4;
robot[rbt].drct = (robot[rbt].drct + 1)%4;

还要注意的是图片的方向和抽象后数组的方向转化,图片中横向是x方向,但数组中,纵向是x方向且向下为x正,则对应关系为

  • 数组x增长方向为东E
  • 数组x递减方向为西W
  • 数组y递增方向为北N
  • 数组y递减方向为南S

最后代码如下

#include <iostream>
#include <stdio.h>
#include <string.h>
//#define TEST
using namespace std;
int board[110][110];
struct ROBOT
{
    int x;
    int y;
    int drct;
}robot[101];

int main()
{
    #ifdef TEST
    freopen("test.txt", "r", stdin);
    #endif // TEST
    int testcase;
    int xi, yi;
    int n, m;
    scanf("%d", &testcase);
    while(testcase--)
    {
        scanf("%d %d", &xi, &yi);
        scanf("%d %d", &n, &m);

        memset(board, 0, sizeof(board));
        memset(robot, 0, sizeof(robot));
        for(int i = 1; i <= n ; i++)
        {
            int x, y;
            char drct;
            scanf("%d %d %c", &x, &y, &drct);
            robot[i].x = x;
            robot[i].y = y;
            //方向转化,方便后面模4运算
            switch(drct)
            {
                case 'E': robot[i].drct = 0;break;
                case 'S': robot[i].drct = 1;break;
                case 'W': robot[i].drct = 2;break;
                case 'N': robot[i].drct = 3;break;
                default:robot[i].drct = 0;
            }
            board[x][y] = i;   //方针对应位置标记为机器人号
        }
        int fail = 0;
        while(m--)
        {
            int rbt, rpt;
            char act;
            scanf("%d %c %d", &rbt, &act, &rpt);
            //must promise input is read
            //保证输入都按要求输入,避免有些提供的数据没有输入导致错误
            if(fail) continue;
            //模4转向,加4可以处理0需要减1的时候
            if(act == 'L')
                for(int i = 0; i < rpt; i++)
                    robot[rbt].drct = (robot[rbt].drct - 1 + 4)%4;
            else if(act == 'R')
                for(int i = 0; i < rpt; i++)
                    robot[rbt].drct = (robot[rbt].drct + 1)%4;
            else if(act == 'F')
            {
                for(int i = 0; i < rpt; i++)
                {
                    int nx, ny;
                    switch(robot[rbt].drct)
                    {
                        case 0: nx = robot[rbt].x + 1; ny = robot[rbt].y; break;
                        case 1: nx = robot[rbt].x; ny = robot[rbt].y-1; break;
                        case 2: nx = robot[rbt].x - 1; ny = robot[rbt].y; break;
                        case 3: nx = robot[rbt].x; ny = robot[rbt].y+1;break;
                        default:nx = robot[rbt].x; ny = robot[rbt].y;
                    }
                    if(nx == 0 || nx == xi+1 || ny == 0 || ny == yi+1)
                    {
                        printf("Robot %d crashes into the wall\n", rbt);
                        fail = 1;
                        break;
                    }
                    else if(board[nx][ny] != 0)
                    {
                        printf("Robot %d crashes into robot %d\n", rbt, board[nx][ny]);
                        fail = 1;
                        break;
                    }
                    else
                    {
                        board[robot[rbt].x][robot[rbt].y] = 0;
                        board[nx][ny] = rbt;
                        robot[rbt].x = nx;
                        robot[rbt].y = ny;
                    }
                }
            }
        }
        if(!fail) printf("OK\n");
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值