人工智能及其应用 实验课 源代码
Posted 行码棋
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了人工智能及其应用 实验课 源代码相关的知识,希望对你有一定的参考价值。
实验一
梵塔问题
#include<bits/stdc++.h>
using namespace std;
using ll = long long;
ll ans = 0;
void dfs(char a, char b, char c, int n)
if(n == 1)
ans++;
cout << a << " -> " << c << "\\n";
else
dfs(a, c, b, n - 1);
ans++;
cout << a << " -> " << c << "\\n";
dfs(b, a, c, n - 1);
int main()
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
dfs('A', 'B', 'C', n);
cout << ans << "\\n";
return 0;
传教士野人渡河问题
#include<bits/stdc++.h>
using namespace std;
const int N = 1e6 + 5;
const int dx[] = 1, 0, 0, 2, 1;
const int dy[] = 1, 2, 1, 0, 0;
array<int, 3> ans[N], tot[N];
map<array<int, 3>, bool> v;
int sum, tt = -1;
int a, b;
// 本岸位置的 野人 和 传教士 数量 1 : 本岸 -1 :对岸
bool check(array<int, 3> t)
int y = t[0], c = t[1], f = t[2];
if(y < 0 || c < 0 || y > a || c > b) return 0;
if((c != 0 && y > c) || (b - c != 0 && a - y > b - c)) return 0;
return 1;
void dfs(array<int, 3> t)
int y = t[0], c = t[1], f = t[2];
if(y == 0 && c == 0 && f == -1)
sum++;
cout << sum << "\\n";
for(int i = 0; i <= tt; i++)
cout << (ans[i][2] == 1 ? "去" : "回") << " ";
cout << "野人:" << ans[i][0] << " 传教士:" << ans[i][1] << "\\n";
return;
array<int, 3> tmp;
for(int i = 0; i < 5; i++)
tmp = y - f * dx[i], c - f * dy[i], -f;
if(check(tmp) && !v[tmp])
v[tmp] = 1;
ans[++tt] = dx[i], dy[i], f;
dfs(tmp);
v[tmp] = 0;
--tt;
int main()
cout << "请分别输入野人数量和传教士数量:";
cin >> a >> b;
array<int, 3> t = a, b, 1;
v[t] = 1;
dfs(t);
v[t] = 0;
return 0;
实验二
宽度优先和深度优先求解路径
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 5, M = 2 * N;
const int inf = 0x3f3f3f3f;
int n, m;
int s, d;
int dis[N], vis[N], pre[N];
int e[M], h[N], ne[M], w[M], idx;
void add(int a, int b, int c)
e[idx] = b, w[idx] = c, ne[idx] = h[a], h[a] = idx++;
void dfs(int u)
vis[u] = 1;
if(u == d) return;
for(int i = h[u]; ~i; i = ne[i])
int to = e[i], val = w[i];
if(!vis[to] || dis[u] + val < dis[to])
dis[to] = dis[u] + val;
pre[to] = u;
dfs(to);
// 只能求不带权图
void bfs(int s)
queue<int> q;
vis[s] = 1;
q.push(s);
while(!q.empty())
int t = q.front();
q.pop();
if(t == d) return;
for(int i = h[t]; ~i; i = ne[i])
int to = e[i];
if(vis[to]) continue;
vis[to] = 1;
dis[to] = dis[t] + 1;
pre[to] = t;
q.push(to);
int main()
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
memset(h, -1, sizeof h);
cin >> n >> m >> s >> d;
for(int i = 1; i <= m; i++)
int a, b, c;
cin >> a >> b >> c;
add(a, b, c);
memset(dis, 0x3f, sizeof dis);
memset(pre, -1, sizeof pre);
dis[s] = 0;
// dfs(s);
bfs(s);
vector<int> path;
int t = d;
path.push_back(t);
while(pre[t] != -1)
path.push_back(pre[t]);
t = pre[t];
reverse(path.begin(), path.end());
cout << "最短的路径:\\n";
for(int i = 0; i < int(path.size() - 1); i++)
cout << path[i] << " -> " << path[i + 1] << "\\n";
cout << "最短路径:" << dis[d] << "\\n";
return 0;
/* sample 1
8 10 1 8
1 2 1
1 5 1
2 5 1
2 3 1
5 3 1
5 6 1
3 4 1
3 7 1
3 8 1
4 8 1
*/
八数码问题
下面代码实现了N数码问题,不仅仅局限于八数码,但是求解效率有限
#include<bits/stdc++.h>
using namespace std;
using pis = pair<int, string>;
const int N = 500 * 500 + 5;
const int dx[] = -1, 0, 1, 0, dy[] = 0, 1, 0, -1;
int n;
template <typename T>
struct Fenwick
vector<T> tr;
const int n;
Fenwick(int n): n(n), tr(n)
void insert(int x, T d)
for(; x < n; x += x & (-x))
tr[x] += d;
T sum(int x)
T res = 0;
for(; x; x -= x & (-x))
res += tr[x];
return res;
T RangeSum(int l, int r)
return sum(r) - sum(l - 1);
;
int f(string s)
int cnt = 0;
for(int i = 0; i < int(s.size()); i++)
if(s[i] != '0')
int cur = s[i] - '1';
cnt += abs(cur / n - i / n) + abs(cur % n - i % n);
return cnt;
void bfs(string start, string end)
char op[] = "URDL";
unordered_map<string, int> dis;
unordered_map<string, pair<char, string>> pre;
priority_queue<pis, vector<pis>, greater<pis>> q;
q.push(f(start), start);
dis[start] = 0;
while(!q.empty())
auto t = q.top();
q.pop();
string st = t.second;
if(st == end) break;
int x, y;
for(int i = 0; i < int(st.size()); i++)
if(st[i] == '0')
x = i / n, y = i % n;
break;
for(int i = 0; i < 4; i++)
int nx = x + dx[i], ny = y + dy[i];
if(nx < 0 || nx >= n || ny < 0 || ny >= n) continue;
string t = st;
swap(t[x * n + y], t[nx * n + ny]);
if(!dis.count(t) || dis[st] + 1 < dis[t])
dis[t] = dis[st] + 1;
pre[t] = op[i], st;
q.push(dis[t] + f(t), t);
string move;
vector<string> state;
state.push_back(end);
while(end != start)
move += pre[end].first;
end = pre[end].second;
state.push_back(end);
reverse(move.begin(), move.end());
reverse(state.begin(), state.end());
for(int i = 0; i < int(move.size()); i++)
int cur = 0;
for(int j = 0; j < n; j++)
for(int k = 0; k < n; k++)
cout << (state[i][cur++] - '0') << " \\n"[k == n - 1];
cout << "-----------------\\n操作:" << move[i] << "\\n";
if(i == int(move.size() - 1))
int nxt = i + 1;
cur = 0;
for(int j = 0; j < n; j++)
for(int k = 0; k < n; k++)
cout << (state[nxt][cur++] - '0') << " \\n"[k == n - 1];
int main()
cout << "输入数码阶数:\\n";
cin >> n;
vector<int> 数据结构—深度优先遍历广度优先遍历图遍历算法的应用