UVaOJ 127 - "Accordian" Patience

——by A Code Rabbit


Description

模拟一个扑克牌游戏,规则是:

  • 从左到右发牌,排成一行。
  • 一共五十二张,所以一开始有五十二叠,然后根据规则进行合并。
  • 只要一张牌与它左边第一张或者第三张牌匹配(点数或花色相同),就可以把牌移动到匹配牌上。
  • 如果某一叠牌被移空,它右边的牌应该左移,补上它的空位。
  • 应该移动到不能移动任何一张牌为止。

在某些情况下,应采取以下策略(最左边原则):

  • 当同时有多张牌可以移动时,应该先移动最左边的牌。
  • 当一张牌与左边的第一张和第三张牌都匹配,则应该移动到最左边的牌。

输入给出发牌的顺序,将这副牌按照规则进行游戏,输出最终结果。


Types

Date Structure :: Lists


Analysis

题目数据量较小,可以模拟一张张牌移动,直到没有牌可以移动为止。

要注意两个策略(最左边原则)。

UVaOJ 的测试点比较严格,模拟要细心。

相比之 POJ 的测试数据较水,很多错误代码都可以AC。

如要要提交到 POJ ,要注意 POJ 的输出和 UVaOJ 不一样。

很多代码TLE的原因其实是代码有错,而不是算法时间复杂度太高。


Solution

// UvaOJ 127
// "Accordian Patience"
// by A Code Rabbit

#include <cstdio>
#include <cstring>

const int LIMITS = 100;

char str[10];

char piles[LIMITS][LIMITS][10];
int top_piles[LIMITS];
int num_piles;

bool Match(char*, char*);
bool Move(int, int);

void Outputs();

int main() {
    while (scanf("%s", str)) {
        // Exit.
        if (str[0] == '#') {
            break;
        }
        // INIT.
        memset(piles, 0, sizeof(0));
        memset(top_piles, 0, sizeof(0));
        num_piles = 0;
        // Inputs.
        strcpy(piles[0][0], str);
        for (int i = 1; i < 52; ++i) {
            scanf("%s", piles[i][0]);
        }
        for (int i = 0; i < 52; ++i) {
            top_piles[i] = 1;
        }
        num_piles = 52;
        // Play the game.
        bool is_moved = true;
        while (is_moved) {
            is_moved = false;
            for (int i = 0; i < num_piles; ++i) {
                if (Move(i - 3, i) || Move(i - 1, i)) {
                    is_moved = true;
                    break;
                }
            }
        }
        // Outputs.
        Outputs();
    }

    return 0;
}

bool Match(char* card_1, char* card_2) {
    return card_1[0] == card_2[0]
        || card_1[1] == card_2[1];
}

bool Move(int pos_1, int pos_2) {
    int& top_1 = top_piles[pos_1];
    int& top_2 = top_piles[pos_2];
    // Avoid subscipt beyond bounds. 
    if (pos_1 < 0) {
        return false;
    }
    // Check up whether two cards is matching.
    if (!Match(piles[pos_1][top_1 - 1], piles[pos_2][top_2 - 1])) {
        return false;
    }
    // Exchange the positions of two cards.
    strcpy(piles[pos_1][top_1], piles[pos_2][top_2 - 1]);
    ++top_1;
    --top_2;
    // Move right piles if the pile is empty.
    if (!top_piles[pos_2]) {
        for (int i = pos_2; i < num_piles - 1; ++i) {
            top_piles[i] = top_piles[i + 1];
            for (int j = 0; j < top_piles[i]; ++j) {
                strcpy(piles[i][j], piles[i + 1][j]);
            }
        }
        --num_piles;
    }

    return true;
}

void Outputs() {
    printf("%d", num_piles);
    if (num_piles > 1) {
        printf(" piles remaining:");
    } else {
        printf(" pile remaining:");
    }
    for (int i = 0; i < num_piles; ++i) {
        printf(" %d", top_piles[i]);
    }
    printf("\n");
}



下载PDF

参考资料:Devymex博客传送门

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值