AtCoder Beginner Contest 339 B.Langton‘s Takahashi【模拟】

原题链接:https://atcoder.jp/contests/abc339/tasks/abc339_b

Time Limit: 2 sec / Memory Limit: 1024 MB

Score: 250 points

问题陈述

有一个行数为 H 列数为 W 的网格,起初所有单元格都涂成白色。让 (i,j) 表示从上往下第 i 行,从左往上第 j 列的单元格。

这个网格被认为是环形的。也就是说,每个1≤i≤H的(i,1)在(i,W)的右边,每个1≤j≤W的(1,j)在(H,j)的下面。

高桥位于(1,1),并且朝上。在高桥重复下面的操作 N 次后,打印出网格中每个单元格的颜色。

  • 如果当前单元格被涂成白色,则将其重新涂成黑色,顺时针旋转90∘,并沿着他面对的方向向前移动一个单元格。否则,将当前单元格重新涂成白色,逆时针旋转 90∘,并沿着他所面对的方向向前移动一个单元格。

限制因素

  • 1≤H,W≤100
  • 1≤N≤1000
  • 所有输入值均为整数。

输入输出描述:

Sample Input 1Copy

3 4 5

Sample Output 1Copy

.#..
##..
....

网格单元格因操作而发生如下变化:

....   #...   ##..   ##..   ##..   .#..
.... → .... → .... → .#.. → ##.. → ##..
....   ....   ....   ....   ....   ....

Sample Input 2Copy

2 2 1000

Sample Output 2Copy

..
..

Sample Input 3Copy

10 10 10

Sample Output 3Copy

##........
##........
..........
..........
..........
..........
..........
..........
..........
#........#

解题思路:

这个题目思路比较简单,直接根据题目说的遇到白色的格子先把这个格子变成黑色,然后顺时针旋转90°,然后向着当前面向的方向前进一步,如果遇到黑色的格子先把这个格子变成白色,然后逆时针旋转90°,然后向着当前面向的方向前进一步。代码实现的关键所在就在于怎么实现顺时针逆时针的方向转变,首先上方顺时针旋转就是90°就是右侧,逆时针旋转90°就是左侧,我们可以发现这个转变不就是bfs中使用的那个往四个方向扩展的dx和dy数组,首先面向上方,相当于dx[0],dy[0],然后顺时针旋转就是都在数组中的下标加1,逆时针旋转90°就是都在数组中的下标减1,只不过要把这个数组搞成循环数组,然后模拟即可。

时间复杂度:首先cnt次操作为O(cnt),cnt=1000,然后输出答案时间复杂度为O(nm),n=100,m=100所以最终时间复杂度为O(cnt+nm).

空间复杂度:O(nm)。

cpp代码如下:

#include 
#include 
#include 
#include 

using namespace std;
typedef long long LL;
typedef pair PII;
const int N = 110;

int n, m, cnt;
char g[N][N];

int dx[4] = {-1, 0, 1, 0}, dy[4] = {0, 1, 0, -1};
void move(int x, int y, int k)
{
    while (cnt--)
    {
        if (g[x][y] == '.')  //遇见白色格子,顺时针旋转之后向着面对的方向前进一步
        {
            g[x][y] = '#';  //将白色格子变为黑色格子
            k = (k + 1 + 4) % 4;  //顺时针旋转,下标+1
            x = (x + dx[k] + n) % n;  //向着面对的方向前进一格
            y = (y + dy[k] + m) % m;
        }
        else     //遇见黑色格子,逆时针旋转之后向着面对的方向前进一步
        {
            g[x][y] = '.';  //将黑色格子变为白色格子
            k = (k - 1 + 4) % 4;  //逆时针旋转,下标-1
            x = (x + dx[k] + n) % n; //向着面对的方向前进一格
            y = (y + dy[k] + m) % m;
        }
    }
}
int main()
{
    cin >> n >> m >> cnt;
    //最开始所有格子都是白色的
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            g[i][j] = '.';
    //模拟移动过程
    move(0, 0, 0);
    //输出答案
    for (int i = 0; i < n; i++)
        puts(g[i]);
    return 0;
}

你可能感兴趣的:(基础算法,算法)