题目描述
2048是大家非常喜欢的一款小游戏,给定一个2048的局面,和下一步的指令,请计算出变化后的局面。 2048的游戏规则如下:
- 游戏是一个4×4的格子
- 玩家可以使用上、下、左、右控制数字方格滑动,
- 每滑动一次,所有的数字方块都会往滑动的方向靠拢,相同数字的方块在靠拢、相撞时会相加。
- 不断的叠加最终拼凑出2048这个数字就算成功
- 每次滑动后,会在某个空白格子中出现随机的2或者4,如果不存在空白格子,则游戏结束。
输入
第一行是一个整数K,表示样例的个数。 每个样例的前4行,每行4个整数,如果整数为0表示空白格子,其他为数字。 每个样例的第5行,是指令,指令为"LEFT","DOWN","RIGHT","UP",依次表示滑动的方向。
输出
输出每个样例的结果,每个样例后输出一个空行。
样例输入
3 2 2 0 0 2 0 2 0 2 0 0 2 0 0 2 2 LEFT 2 0 2 0 2 2 2 2 0 2 0 2 4 2 2 0 LEFT 2 4 2 2 0 2 2 0 0 4 4 4 0 0 0 2 LEFT样例输出
4 0 0 0 4 0 0 0 4 0 0 0 4 0 0 0 4 0 0 0 4 4 0 0 4 0 0 0 4 4 0 0 2 4 4 0 4 0 0 0 8 4 0 0 2 0 0 0
解题思路:这题又是一道大模拟,2048应该都玩过,具体步骤没什么多说的,就讲讲如何更新执行完指令后的结果。其实简单来说就两步。
1:按指令的方向,把 相同的数加在一起(加的数*2,被加的数置0)。比如左滑:2 2 2 2 —> 4 0 4 0 ; 2 0 0 2 —> 4 0 0 0 ; 2 0 2 1—> 4 0 0 1; 2 0 4 8 —> 2 0 4 8。
2:把非0的数,按指令的方向移动,把0放在 相反方向。 比如:2 2 2 2 —> 4 0 4 0 —> 4 4 0 0 ;2 0 2 1—> 4 0 0 1 —> 4 1 0 0;2 0 4 8 —> 2 0 4 8 —> 2 4 8 0。
执行完这两步,也就是完成了一次2048指令了。具体请看代码。
AC代码:
#include <stdio.h>
char ins[7];
int game[7][7];
int tag1,tag2,flag;
void swap(int &x,int &y){ // 交换函数
int t;
t = x, x = y, y = t;
}
void exchange1(int i) // 左滑
{
tag1 = tag2 = -1, flag = true; // tag1存下标,tag2存数值
for (int j = 1; j <= 4; j ++) // 把可以合并的数合并起来
{
if (game[i][j] == 0) continue; // 如果是0,跳过
if (game[i][j] != tag2) // 两个数不一样,更新。 比如 1 2 0 2, j = 2时, 2和1不一样,更新记录2
{tag1 = j, tag2 = game[i][j]; continue;}
if (game[i][j] == tag2) // 两个数相同,相加。(接上)j = 4时,2 与前面的2相同,相加。
{
game[i][tag1] *= 2, game[i][j] = 0;
tag1 = tag2 = -1; // 2048规则是一次指令中,对相同的数只加一次。比如
} // 2 2 2 0 , 只会加成 4 2 0 0 ,不好成 6 0 0 0
}
while (flag) // 把 >0的数,向左填充。
{
flag = false; // 默认都向左填充好了,不要移位了。
for (int j = 1; j < 4; j ++)
if (game[i][j] == 0 && game[i][j+1] != 0) // 如果前一位是0,后一位非0,把非0数左移。
swap(game[i][j], game[i][j+1]), flag = true; //移过一次就重新记 true。
} // 如果最后flag 还是 false,说明该轮没用移动过数,那么说明已经排好了,跳出循环。
}
void exchange2(int i)
{
tag1 = tag2 = -1, flag = true;
for (int j = 4; j >= 1; j --)
{
if (game[i][j] == 0) continue;
if (game[i][j] != tag2)
{tag1 = j, tag2 = game[i][j]; continue;}
if (game[i][j] == tag2)
{
game[i][tag1] *= 2, game[i][j] = 0;
tag1 = tag2 = -1;
}
}
while (flag)
{
flag = false;
for (int j = 4; j > 1; j --)
if (game[i][j] == 0 && game[i][j-1] != 0)
swap(game[i][j], game[i][j-1]), flag = true;
}
}
void exchange3(int i)
{
tag1 = tag2 = -1, flag = true;
for (int j = 4; j >= 1; j --)
{
if (game[j][i] == 0) continue;
if (game[j][i] != tag2)
tag1 = j, tag2 = game[j][i];
else if (game[j][i] == tag2)
{
game[tag1][i] *= 2, game[j][i] = 0;
tag1 = tag2 = -1;
}
}
while (flag)
{
flag = false;
for (int j = 4; j > 1; j --)
if (game[j][i] == 0 && game[j-1][i] != 0)
swap(game[j][i], game[j-1][i]), flag = true;
}
}
void exchange4(int i)
{
tag1 = tag2 = -1, flag = true;
for (int j = 1; j <= 4; j ++)
{
if (game[j][i] == 0) continue;
if (game[j][i] != tag2)
tag1 = j, tag2 = game[j][i];
else if (game[j][i] == tag2)
{
game[tag1][i] *= 2, game[j][i] = 0;
tag1 = tag2 = -1;
}
}
while (flag)
{
flag = false;
for (int j = 1; j < 4; j ++)
if (game[j][i] == 0 && game[j+1][i] != 0)
swap(game[j][i], game[j+1][i]), flag = true;
}
}
int main()
{
int T;
scanf("%d",&T);
while ( T --)
{
for (int i = 1; i <= 4; i ++)
for (int j = 1; j <= 4; j ++)
scanf("%d",&game[i][j]);
scanf("%s",ins);
if (ins[0] == 'L') // 按指令操作
for (int i = 1; i <= 4; i ++)
exchange1(i);
else if (ins[0] == 'R')
for (int i = 1; i <= 4; i ++)
exchange2(i);
else if (ins[0] == 'D')
for (int i = 1; i <= 4; i ++)
exchange3(i);
else
for (int i = 1; i <= 4; i ++)
exchange4(i);
for (int i = 1; i <= 4; i ++) // 输出
{
for (int j = 1; j <= 3; j ++)
printf("%d ",game[i][j]);
printf("%d\n",game[i][4]);
}
puts("");
}
return 0;
}