Problem B. Super 2048 - APAC Test 2015 Round A(模拟)

链接

https://code.google.com/codejam/contest/3214486/dashboard#s=p1

题意

基于2048,不过格子大小变为了 NN
现在给定一个状态,和当前的操作(上下左右),求下一个状态

思路

模拟一下就好。
比如向右滑动,那么每一行单独处理,指针指向 N1 的位置,和其右边的一个合并(如果能合并即合并且指针左移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();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值