题目信息
小张非常喜欢与朋友们玩成语接龙的游戏,但是作为“文化沙漠”的小张,成语的储备量有些不足。现在他的大脑中存储了 m 个成语,成语中的四个汉字都用一个1000000以内的正整数来表示。现在小张的同学为了考验他给出了他一个成语做开头和一个成语做结尾,如果小张能通过成语接龙的方式说到结尾的成语,他就能够成功完成游戏。他想知道最少能说几个成语能够成功完成游戏。
输入
第一行一个数 m(1 ≤ m ≤ 300000 )
。
接下来 m 行,每行4个1000000以内的正整数,表示一个成语。
下一行4个1000000以内的正整数,表示开始成语。
下一行4个1000000以内的正整数,表示结束成语。
保证开始成语和结束成语在小张的成语储备之中。
输出
一行一个整数,表示最少说几个成语能够完成游戏。如果无法完成输出-1。
提示
三个成语分别是(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
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
1
解答
#include <bits/stdc++.h>
using namespace std;
struct BiaoJi
{
long ChengYu;
bool visit;
BiaoJi(long ChengYu_, bool visit_)
{
ChengYu = ChengYu_;
visit = visit_;
}
};
vector<BiaoJi> g[300000 + 10];
struct Pos
{
public:
long id;
long step;
Pos(long id_, long step_) : id(id_), step(step_)
{}
};
struct ChengYu
{
public:
long ChengYuA;
long ChengYuB;
long ChengYuC;
long ChengYuD;
};
queue<Pos> q;
int main()
{
//freopen("E://test.txt", "r", stdin);
long m;
cin >> m;
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;
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;
}
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++)
{//遍历这一行vector
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;
}