#include "guanka2.h"
//#include "enter.h"
#include <iostream>
#include <vector>
#include <climits>
#include <algorithm>
#include <string>
#include <iomanip> // 用于对齐输出
#include <set>
using namespace std;
const int NUM_CITIES = 5;
// 距离矩阵(99 表示不可达)
int dist[NUM_CITIES][NUM_CITIES] = {
{0, 10, 99, 4, 12}, // 0: 魔法学院
{10, 0, 15, 8, 5 }, // 1: 图书馆
{99, 15, 0, 7, 30}, // 2: 法师塔
{4, 8, 7, 0, 6 }, // 3: 宿舍
{12, 5, 30, 6, 0 } // 4: 城堡
};
// 地点名称
string cityNames[NUM_CITIES] = {
"魔法学院",
"图书馆",
"法师塔",
"宿舍",
"城堡"
};
int colWidth = 14;
//手动暂停函数:等待按回车
void press_enter_to_continue2() {
cout << "\n按回车键继续...";
cin.get(); // 吃掉之前的换行
while (cin.get() != '\n'); // 再次等待用户按回车
}
// 输出美化版的距离矩阵
void printDistanceMatrix() {
cout << "根据上一关你找到的地图信息:\n";
cout << "\n各地点之间的通行耗时(单位:分钟) ===\n\n";
// 表头:城市名
cout << setw(colWidth) << " ";
for (int i = 0; i < NUM_CITIES; ++i) {
cout << "|" << setw(colWidth - 1) << cityNames[i];
}
cout << "\n";
cout << string(colWidth + NUM_CITIES * colWidth, '-') << "\n";
// 数据行
for (int i = 0; i < NUM_CITIES; ++i) {
cout << setw(colWidth) << cityNames[i];
for (int j = 0; j < NUM_CITIES; ++j) {
cout << "|";
if (dist[i][j] >= 99) {
cout << setw(colWidth - 1) << "×";
}
else {
cout << setw(colWidth - 1) << dist[i][j];
}
}
cout << endl;
}
cout << endl;
cout << " 说明:\n";
cout << " • × 表示两地之间无法直接到达\n";
cout << " • 数字表示所需时间(分钟)\n";
cout << " • 必须从【" << cityNames[0] << "】出发,最终停在【" << cityNames[4] << "】\n";
cout << " • 所有地点必须访问一次且仅一次!\n";
}
// 计算某条路径的总耗时
int calculateTime(const vector<int>& path) {
int total = 0;
for (int i = 0; i < NUM_CITIES - 1; ++i) {
int from = path[i];
int to = path[i + 1];
if (dist[from][to] >= 99) {
return INT_MAX; // 不可达
}
total += dist[from][to];
}
return total;
}
// 求出理论上的最短时间(自动枚举所有合法路径)
int findOptimalTime() {
vector<int> perm;
for (int i = 0; i < NUM_CITIES; ++i)
perm.push_back(i);
int best = INT_MAX;
do {
// 检查是否从 0(魔法学院)开始,且以 4(城堡)结束
if (perm[0] != 0 || perm[NUM_CITIES - 1] != 4) continue;
int time = calculateTime(perm);
if (time < best) {
best = time;
}
} while (next_permutation(perm.begin(), perm.end()));
return best;
}
bool playguanka2() {
// 开始剧情
cout << "欢迎来到第二关!\n";
cout << "这一次你的任务是从【魔法学院】出发,\n";
cout << "依次探访所有重要地点,并最终抵达【城堡】参加晚宴。\n";
cout << "但时间紧迫!请规划一条最短路线!\n\n";
press_enter_to_continue2();
cout << "点击查看地图信息" << endl;
press_enter_to_continue2();
// 显示地图信息
printDistanceMatrix();
press_enter_to_continue2();
cout << " 规则回顾:\n";
cout << " 1. 起点:魔法学院(编号1)\n";
cout << " 2. 终点:城堡(编号5)\n";
cout << " 3. 每个地点只能访问一次\n";
cout << " 4. 请按顺序输入你要访问的地点编号(1~5),用空格分隔:\n";
cout << "\n 地点编号对应表:\n";
for (int i = 0; i < NUM_CITIES; ++i) {
cout << " [" << (i + 1) << "] " << cityNames[i] << endl;
}
cout << "\n请输入你的路线规划(例如:1 4 2 3 5):\n";
// 玩家输入路径(1~5)
vector<int> player_path(NUM_CITIES);
for (int i = 0; i < NUM_CITIES; ++i) {
cin >> player_path[i];
player_path[i]--; // 转为 0~4 的索引
}
// --- 验证输入 ---
// 1. 是否包含重复或非法数字?
set<int> seen;
bool valid = true;
for (int idx : player_path) {
if (idx < 0 || idx >= NUM_CITIES || seen.count(idx)) {
valid = false;
}
seen.insert(idx);
}
if (!valid) {
cout << "\n 输入无效!必须是 1 到 5 的不重复数字。\n";
cout << "路线规划失败。\n";
return false;
}
// 2. 是否从魔法学院(0)开始?
if (player_path[0] != 0) {
cout << "\n 错误:必须从【魔法学院】出发!\n";
cout << "路线规划失败。\n";
return false;
}
// 3. 是否以城堡(4)结束?
if (player_path[NUM_CITIES - 1] != 4) {
cout << "\n 错误:必须最终抵达【城堡】!\n";
cout << "路线规划失败。\n";
return false;
}
// 4. 计算玩家所用时间
int player_time = calculateTime(player_path);
if (player_time == INT_MAX) {
cout << "\n 路线中存在不可达路段(×),无法通行!\n";
cout << "路线规划失败。\n";
return false;
}
// 5. 获取理论最短时间
int optimal_time = findOptimalTime();
// --- 判断是否成功 ---
cout << "\n 正在分析你的路线...\n";
for (int i = 0; i < NUM_CITIES; ++i) {
cout << cityNames[player_path[i]];
if (i != NUM_CITIES - 1) cout << " → ";
}
cout << "\n 你所用时间:" << player_time << " 分钟\n";
if (player_time == optimal_time) {
cout << "\n 恭喜!你找到了最短路径!\n";
return true;
}
else {
cout << " 很遗憾,这不是最快路线,请再试试看吧!\n";
return false;
}
cout << "\n 第二关完成!即将进入第三关\n";
press_enter_to_continue2();
}
列举实验中实现算法的主要函数,并对函数作简要说明
最新发布