首页 > 技术文章 > PTA 7-8 卡片邻居游戏 (50 分) Java作业

weilinfox 2021-05-19 13:45 原文

2021-05-19

可以说是我做过比较神奇的题了。

原题

有个游戏叫卡片邻居游戏,它使用多张正方形的卡片,每张卡片在上下左右四边上有数字,可以顺时针旋转,如下图所示。

卡片邻居游戏1

卡片在游戏板上被放成一排,相邻两张卡片的邻边应当具有相同的数字,不断有新的卡片需要放置到游戏板上,放置的位置应当满足相临边数字相同的要求(亦可放在头部和尾部)。下图展示了游戏板上的一组卡片排列和新增一张卡片后的游戏板

卡片邻居游戏2
卡片邻居游戏3

完成类NumberCard,包含构造函数和方法 rotate 和 getLeft,getRight,分别表示顺时针旋转卡片,返回左侧数字,返回右侧数字

完成类CardGame表示游戏版,包含方法int getIndexForFit(NameCard),boolean insertCard(NameCard),print() 其中getIndexForFit返回用最少的旋转数能将卡片插入到游戏板中的最靠前的位置,头部位置为0. insertCard将卡片通过最少的旋转插入到游戏板,按旋转完成的方向插入getIndexForFit返回的位置,返回插入成功与否。print函数按顺序输出每个卡片,每个卡片按照上右下左的顺序输出各个边上的数字。(注:应当选择适当的结构存储游戏板中的卡片)

输入格式:

插入新的卡片的个数 每个新插入的新卡片,按上右下左顺序

输出格式:

依次输出游戏板上各个卡片,按上右下左的顺序

输入样例:

在这里给出一组输入。例如:

3
1 2 3 4
6 4 3 3
4 3 7 4

输出样例:

在这里给出相应的输出。例如:

4 3 7 4 6 4 3 3 1 2 3 4

题解

其实最让我奇怪的是两个最:用最少的旋转数能将卡片插入到游戏板中的最靠前的位置,那么总归有一个优先次序吧;次奇怪的点是 insertCard 具有 boolean 类型的返回值,难不成有些不能插入成功?

有这两个疑问,我一直没想出来比较好的解决办法,直到有一个人做出来了,他的博客在这里。里面有一段话:

最后一个测试点有问题,最后一个数据没插入,应该是可以的,而且这个测试点的数据还不能旋转(我的函数都写错了,这么看好像所有的测试点都不用旋转/捂脸),然后就卡bug过了…

这解决了我的疑问:压根不旋转,如果没有位置可以插入,就舍弃而不插入。

所以这个题想表明什么XD,我觉得可能题目本意就是这样,但是题面写错了。毕竟Java作业,而不是算法。

最后附上我的AC代码:

import java.util.*;

public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        NumberCard nc = new NumberCard(sc);
        CardGame cg = new CardGame(sc);
        int num = cg.getNum();
        for (int i = 0 ; i < num; i++) {
            nc.scan();
            cg.insertCard(nc);
        }
        cg.print();
        sc.close();
    }
}

class NumberCard {
    private int up, down, left, right;
    private Scanner sc;
    public NumberCard() {}
    public NumberCard(Scanner _sc) {
        sc = _sc;
    }
    public void set(NumberCard c) {
        up = c.up; down = c.down; left = c.left; right = c.right;
    }
    public void rotate() {
        int tmp = up;
        up = left; left = down; down = right; right = tmp;
    }
    public int getLeft() {
        return left;
    }
    public int getRight() {
        return right;
    }
    public int getUp() {
        return up;
    }
    public int getDown() {
        return down;
    }
    public void print() {
        System.out.printf("%d %d %d %d", up, right, down, left);
    }
    public void scan() {
        up = sc.nextInt();
        right = sc.nextInt();
        down = sc.nextInt();
        left = sc.nextInt();
    }
}

class CardGame {
    private int num;
    private NumberCard[] cards;
    private Scanner sc;
    private int pos;

    public CardGame(Scanner _sc) {
        sc = _sc;
        num = sc.nextInt();
        cards = new NumberCard[num];
        pos = -1;
    }
    public int getIndexForFit(NumberCard c) {
        if (pos == -1) return 0;
        if (c.getRight() == cards[0].getLeft()) return 0;

        int _pos;
        for (_pos = 1 ; _pos <= pos; _pos++) {
            if (c.getLeft() == cards[_pos - 1].getRight() && c.getRight() == cards[_pos].getLeft())
                break;
        }
        if (_pos > pos && c.getLeft() != cards[pos].getRight()) return -1;
        return _pos;
    }
    public boolean insertCard(NumberCard c) {
        int _pos = getIndexForFit(c);
        if (_pos == -1) return false;

        pos++;
        cards[pos] = new NumberCard();
        for (int i = pos; i > _pos; i--) {
            cards[i].set(cards[i-1]);
        }
        cards[_pos].set(c);
        return true;
    }
    public int getNum() {
        return num;
    }
    public void print() {
        for (int i = 0; i <= pos; i++) {
            if (i > 0) System.out.print(" ");
            cards[i].print();
        }
    }
}

by SDUST weilinfox

推荐阅读