蓝桥杯_PREV-33_兰顿蚂蚁 【模拟】

题目链接

问题描述

给定一个m*n的矩形,每个格子上有0,1,两种形态,0代表白,1代表黑。
蚂蚁要移动k次,移动规则:
若蚂蚁在黑格,右转90度,将该格改为白格,并向前移一格;
若蚂蚁在白格,左转90度,将该格改为黑格,并向前移一格。

现在给你一个兰顿蚂蚁的位置,和他头的方向,要走的步数,问最后这个蚂蚁会在什么位置停下。

解题思路

除去题目中的移动规则,这道题就是非常简单的模拟题,走k步就可以了,但是因为题目中“简单”的移动规则,导致模拟的情况就非常多。
首先是: 上下左右分别用:UDLR表示。
UDLR 在 0、1上又有不同的转向。
为了方便,我们用借助map来实现他的转弯,具体移动情况可以参考代码部分。
最后要特别注意的一点,每走一步上一个格子需要变颜色

代码部分

#include <cstdio>  
#include <cstring>  
#include <string>  
#include <iostream>  
#include <queue>
#include <map>

using namespace std;  
typedef pair<char, int> tur; // 拐弯
map <tur, char> cha;//变向 
map <char, int> fx;  // 具体走向 
int dir[4][2] = {-1, 0, 1, 0, 0, -1, 0, 1}; 
const int maxn = 1e2 + 10;
int mat[maxn][maxn];
int m, n;
int sx, sy, k;
char c;
void init()
{
    // 方向 
    fx['U'] = 0;
    fx['D'] = 1;
    fx['L'] = 2;
    fx['R'] = 3;
    //八种转弯情况如下所示,0代表白,1代表黑。
    //上下左右分别用:UDLR表示
    tur tmp;
    tmp.first = 'U', tmp.second = 0;
    cha[tmp] = 'L';
    tmp.first = 'U', tmp.second = 1;
    cha[tmp] = 'R';

    tmp.first = 'D', tmp.second = 0;
    cha[tmp] = 'R';
    tmp.first = 'D', tmp.second = 1;
    cha[tmp] = 'L';

    tmp.first = 'L', tmp.second = 0;
    cha[tmp] = 'D';
    tmp.first = 'L', tmp.second = 1;
    cha[tmp] = 'U';

    tmp.first = 'R', tmp.second = 0;
    cha[tmp] = 'U';
    tmp.first = 'R', tmp.second = 1;
    cha[tmp] = 'D';
} 
void dfs(int x, int y, char c, int k)//模拟蚂蚁的移动
{
    if(k == 0)
    {
        cout << x << " " << y << endl;
        return;
    }
    tur tmp;
    tmp.first = c;
    tmp.second = mat[x][y];
    if(mat[x][y] == 1)
        mat[x][y] = 0;
    else
        mat[x][y] = 1;
    dfs(dir[fx[cha[tmp]]][0] + x, dir[fx[cha[tmp]]][1] + y, cha[tmp], k - 1);
}
int main()  
{  
    init();
    cin >> m >> n;
    for(int i = 0; i < m; ++ i)
    {
        for(int j = 0; j < n; ++ j)
        {
            cin >> mat[i][j];
        }
    }
    cin >> sx >> sy >> c >> k;
    dfs(sx, sy, c, k);
    return 0;
}   
&& pa_Cur->data <= max) // 如果当前节点的值在[min,max]的范围内 { pb_Tail->next = pa_Cur; // 将当前节点加入b链表 pb_Tail = pa_Cur; // pb_Tail指向链表b的尾部节点 pa_Prev->next = pa_Cur->next; // 把当前节点从链表a中删除 pa_Cur = pa_Cur->next; // pa_Cur指向下一个节点 pb_Tail->next = NULL; // 断开b链表的尾部节点与下一个节点的连接 iRet++; // 计数器加1 } else { *no = AddNode(*no, pa_Cur->data); // 如果当前节点的值不在[min,max]的范围内,把它加入no链表 pa_Prev = pa_Cur; // pa_Prev指向当前节点 pa_Cur = pa_Cur->next; // pa_Cur指向下一个节点 iPos++; // iPos指向下一个节点的位置 } } return iRet; // 返回b链表中节点的数量 } 此代码为一个函数,包含5个参数: - LinkList a:链表a的头结点 - LinkList* b:指向链表b的头指针(链表b中的节点大于等于min且小于等于max) - LinkList* no:指向链表no的头指针(链表no中的节点不在[min,max]的范围内) - DataType min:最小值 - DataType max:最大值 代码的功能是:把链表a中值在[min,max]范围内的节点剔除,并加入到链表b中;把链表a中值不在[min,max]范围内的节点,加入到链表no中。函数的返回值为链表b中节点的数量。 具体解释: 首先定义了3个指针变量:pa_Cur、pa_Prev、pb_Tail。pa_Cur表示当前节点,pa_Prev表示当前节点的前一个节点,pb_Tail表示节点b的尾部节点。 然后进入while循环,遍历链表a的每个节点,如果当前节点的值在[min,max]范围内,则把它加入到链表b中,并从链表a中删除。如果当前节点的值不在[min,max]范围内,则把它加入到链表no中。 最后返回链表b中节点的数量。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值