链接
https://code.google.com/codejam/contest/3214486/dashboard#s=p1
题意
基于2048,不过格子大小变为了
N⋅N
现在给定一个状态,和当前的操作(上下左右),求下一个状态
思路
模拟一下就好。
比如向右滑动,那么每一行单独处理,指针指向
N−1
的位置,和其右边的一个合并(如果能合并即合并且指针左移2位,否则指针左移一位)。但是要注意的是如果当前指针指向的数是0,那么左移到第一个不为0的数。
注意上面的0合并完后,里面的0还需要重新合并。
代码
#include <bits/stdc++.h>
using namespace std;
inline int in() {int x; scanf("%d", &x); return x;}
#define pr(x) {cout << #x << ' ' << x << endl;}
const int maxn = 25;
int a[maxn][maxn], n, dir;
string dirs;
void read() {
n = in();
cin >> dirs;
for (int i = 1; i <= n; i++)
for (int j = 1; j <= n; j++)
a[i][j] = in();
}
bool judge_lr(int ind, string dirs) {
if (dirs == "right")
return ind >= 1;
else
return ind <= n;
}
bool judge_up(int ind, string dirs) {
if (dirs == "up")
return ind <= n;
else
return ind >= 1;
}
void merge_lr(int row, int& ind, string dir) {
if (dir == "right") {
if (a[row][ind] == a[row][ind + 1]) {
a[row][ind + 1] *= 2;
a[row][ind] = 0;
ind -= 2;
} else {
if (a[row][ind] == 0) {
int pos = ind + 1;
while (a[row][ind] == 0 && ind > 1)
ind -= 1;
if (ind >= 1) {
if (a[row][ind] == a[row][pos]) {
a[row][pos] *= 2;
a[row][ind] = 0;
ind -= 2;
} else {
ind -= 1;
}
}
} else {
ind -= 1;
}
}
} else {
if (a[row][ind] == a[row][ind - 1]) {
a[row][ind - 1] *= 2;
a[row][ind] = 0;
ind += 2;
} else {
if (a[row][ind] == 0) {
int pos = ind - 1;
while (a[row][ind] == 0 && ind < n)
ind += 1;
if (ind <= n) {
if (a[row][ind] == a[row][pos]) {
a[row][pos] *= 2;
a[row][ind] = 0;
ind += 2;
} else {
ind += 1;
}
}
} else {
ind += 1;
}
}
}
}
void merge_up(int& ind, int col, string dirs) {
if (dirs == "down") {
if (a[ind][col] == a[ind + 1][col]) {
a[ind + 1][col] *= 2;
a[ind][col] = 0;
ind -= 2;
} else {
if (a[ind][col] == 0) {
int pos = ind + 1;
while (a[ind][col] == 0 && ind > 1)
ind -= 1;
if (ind >= 1) {
if (a[ind][col] == a[pos][col]) {
a[pos][col] *= 2;
a[ind][col] = 0;
ind -= 2;
} else {
ind -= 1;
}
}
} else {
ind -= 1;
}
}
} else {
if (a[ind][col] == a[ind - 1][col]) {
a[ind - 1][col] *= 2;
a[ind][col] = 0;
ind += 2;
} else {
if (a[ind][col] == 0) {
int pos = ind - 1;
while (a[ind][col] == 0 && ind < n)
ind += 1;
if (ind <= n) {
if (a[ind][col] == a[pos][col]) {
a[pos][col]*= 2;
a[ind][col] = 0;
ind += 2;
} else {
ind += 1;
}
}
} else {
ind += 1;
}
}
}
}
void merge_zero_lr(int row, string dirs) {
vector<int> v;
if (dirs == "right") {
for (int j = 1; j <= n; j++) {
if (a[row][j]) v.push_back(a[row][j]);
}
for (int j = n; j >= 1; j--) {
if (v.size()) {
a[row][j] = v.back();
v.pop_back();
} else {
a[row][j] = 0;
}
}
} else {
for (int j = n; j >= 1; j--) {
if (a[row][j]) v.push_back(a[row][j]);
}
for (int j = 1; j <= n; j++) {
if (v.size()) {
a[row][j] = v.back();
v.pop_back();
} else {
a[row][j] = 0;
}
}
}
}
void merge_zero_up(int col, string dirs) {
vector<int> v;
if (dirs == "down") {
for (int i = 1; i <= n; i++) {
if (a[i][col]) v.push_back(a[i][col]);
}
for (int i = n; i >= 1; i--) {
if (v.size()) {
a[i][col] = v.back();
v.pop_back();
} else {
a[i][col] = 0;
}
}
} else {
for (int i = n; i >= 1; i--) {
if (a[i][col]) v.push_back(a[i][col]);
}
for (int i = 1; i <= n; i++) {
if (v.size()) {
a[i][col] = v.back();
v.pop_back();
} else {
a[i][col] = 0;
}
}
}
}
void solve_lr() {
for (int i = 1; i <= n; i++) {
int ind = (dirs == "left" ? 2 : n - 1);
while (judge_lr(ind, dirs)) {
merge_lr(i, ind, dirs);
}
merge_zero_lr(i, dirs);
}
}
void solve_ud() {
for (int j = 1; j <= n; j++) {
int ind = (dirs == "up" ? 2 : n - 1);
while (judge_up(ind, dirs))
merge_up(ind, j, dirs);
merge_zero_up(j, dirs);
}
}
void solve() {
if (dirs == "left" || dirs == "right")
solve_lr();
else
solve_ud();
}
void printans() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
printf("%d ", a[i][j]);
}
printf("\n");
}
}
int main() {
int T = in(), kase = 0;
while (T--) {
read();
solve();
printf("Case #%d:\n", ++kase);
printans();
}
}