成语接龙(C++语言)

Description
小张非常喜欢与朋友们玩成语接龙的游戏,但是作为“文化沙漠”的小张,成语的储备量有些不足。现在他的大脑中存储了 m 个成语,成语中的四个汉字都用一个1000000以内的正整数来表示。现在小张的同学为了考验他给出了他一个成语做开头和一个成语做结尾,如果小张能通过成语接龙的方式说到结尾的成语,他就能够成功完成游戏。他想知道最少能说几个成语能够成功完成游戏。

Input
第一行一个数 m(1 ≤ m ≤ 300000 ) 。
接下来 m 行,每行4个1000000以内的正整数,表示一个成语。
下一行4个1000000以内的正整数,表示开始成语。
下一行4个1000000以内的正整数,表示结束成语。
保证开始成语和结束成语在小张的成语储备之中。

Output
一行一个整数,表示最少说几个成语能够完成游戏。如果无法完成输出-1。

Notes
三个成语分别是(1,2,3,4)(4,5,6,7)(7,8,9,10)


样例

输入(1)

5
1 2 3 4
4 5 6 7
7 8 9 10
4 6 6 1
1 6 8 8
1 2 3 4
7 8 9 10

输出(1)

3

输入(2)

5
1 2 3 4
4 5 6 7
7 8 9 10
4 6 6 1
1 6 8 8
1 2 3 4
1 2 3 4

输出(2)

1

代码

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

struct ChengYu {
    long ChengYuA;
    long ChengYuB;
    long ChengYuC;
    long ChengYuD;
};

struct BiaoJi {
    long ChengYu;
    bool visit;

    BiaoJi(long ChengYu_, bool visit_) {
        ChengYu = ChengYu_;
        visit = visit_;
    }
};

struct Pos {
    long id;
    long step;

    Pos(long id_, long step_) : id(id_), step(step_) {}
};

vector<BiaoJi> g[300000 + 10];
queue<Pos> q;

int main() {
    long m;
    cin >> m;

    // Read in ChengYu information and build the graph
    for (long i = 0; i < m; i++) {
        ChengYu tmp;
        cin >> tmp.ChengYuA >> tmp.ChengYuB >> tmp.ChengYuC >> tmp.ChengYuD;
        g[tmp.ChengYuA].push_back(BiaoJi(tmp.ChengYuD, 0));
    }

    ChengYu ChengYustart, ChengYuend;
    cin >> ChengYustart.ChengYuA >> ChengYustart.ChengYuB >> ChengYustart.ChengYuC >> ChengYustart.ChengYuD
        >> ChengYuend.ChengYuA >> ChengYuend.ChengYuB >> ChengYuend.ChengYuC >> ChengYuend.ChengYuD;

    // Check for special cases
    if (ChengYustart.ChengYuA == ChengYuend.ChengYuA && ChengYustart.ChengYuB == ChengYuend.ChengYuB &&
        ChengYustart.ChengYuC == ChengYuend.ChengYuC && ChengYustart.ChengYuD == ChengYuend.ChengYuD) {
        cout << 1 << endl;
        return 0;
    }
    if (ChengYustart.ChengYuD == ChengYuend.ChengYuA) {
        cout << 2 << endl;
        return 0;
    }

    // Perform BFS to find the minimum steps
    Pos PosStart(ChengYustart.ChengYuD, 0);
    q.push(PosStart);
    long MIN = 300000 + 10;

    while (!q.empty()) {
        Pos tmp = q.front();
        for (long i = 0; i < g[tmp.id].size(); i++) {
            if (g[tmp.id][i].visit == 0) {
                if (g[tmp.id][i].ChengYu == ChengYuend.ChengYuA) {
                    if (tmp.step + 3 <= MIN) {
                        MIN = tmp.step + 3;
                    }
                }
                g[tmp.id][i].visit = 1;
                Pos ReturnPos(g[tmp.id][i].ChengYu, tmp.step + 1);
                q.push(ReturnPos);
            }
        }
        q.pop();
    }

    if (MIN != 300000 + 10) {
        cout << MIN << endl;
    } else {
        cout << -1 << endl;
    }

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值