文章

2

粉丝

34

获赞

2

访问

1.5k

头像
2048游戏 题解:简洁实现
P1472
发布于2024年5月5日 15:06
阅读数 1.1k

过了之后本来想看看有没有好玩的解法的,但是看到目前的题解都比较臃肿,要用100行以上代码实现,就打算分享一下自己的50+行代码的思路。

一、简洁实现四个方向

代码长主要是因为要实现四个方向的遍历,如果写四遍两层循环就巨麻烦

观察可以发现,只要对循环变量i j做一定的变换,就能同时代表4个方向,这样只需要写一次两层循环,在循环内写四行if else即可,大大减少代码量。

1. 上键

先来看1的,即用户按向上的键,遍历方向应该是一列列来,从上面到下面

两次循环即

for(int i=0;i<4;i++)
    for(int j=0;j<4;j++)

第一层循环应该是遍历的每一列(即 arr[?][i] ),可以从0到1;而第二层循环应该是遍历某一列的从上到下(即 arr[j][?] ),必须从0到3

2. 下键

同样的如果是2,即用户按向下的键,遍历方向也是一列列来,但是要从下面到上面:第一层遍历不变,第二层遍历必须是从3到0,代码可以写成( arr[3-j][0] )

3. 左键

很明显这个时候要一行行遍历,从左到右

第一层循环会变成遍历数组的每一行( arr[i][?] );第二层循环变成某一行的0列到3列,即arr[?][j]

4. 右键

同理,第一层循环是遍历数组的每一行arr[i][?];第二层循环是遍历某一行的3列到0列arr[?][3-j]

二、实现合并

(下面的例子均假设为按右键,数字向右合并)

数字碰到跟自己一样的就会合并,比如0 0 2 2 -> 0 0 0 4,如上文,按右键时我的遍历方向是从右到左,我就用一个变量last记录上一个遇到的是谁,如果这一次遇到的数字跟上一次相同,那就合并,并置last=0,因为只能合并一次,合并的结果扔去一个vector<int> v里面(push_back,因此顺序也是正确的),这个v是指这一行/列的合并结果,这些数字都会聚集到这一行/列的顶端

有一个小细节,如果遇到了0,我的做法是当作没有数字,直接跳过

还有一个小细节,如果遇到的不是0,但是last又不等于这个数字,说明不能合并,我会把last的值直接扔进v里,再用当前数字覆盖掉la...

登录查看完整内容


登录后发布评论

暂无评论,来抢沙发