标签:cor int ++ 数码 dx dy include
Acwing845.八数码
这种题有个特征就是状态图
迅速判重
原来3×3的矩阵需要\(9!×9!\)次检查,每个状态要和\(9!\)对比
康托展开
每个状态和康托的哈希函数进行判重
时间复杂度:
\[O(n!n!) →O(n!n^2) \]
long int factory[] = {1, 1, 2, 6, 24, 120, 720, 5040, 40320, 362880}
bool Cantor(int str[], int n)
{
long result = 0;
for (int i = 0; i < n; i ++ )
{
int counted = 0;
for (int j = i + 1; j < n; j ++ )
{
if (str[i] > str[j]) ++ counted;
}
result += counted * factory[n - i - 1];
}
if (!visited[result])
{
visited[result] = 1;
return true;
}
return 0;
}
用隐时图的概念
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <unordered_map>
using namespace std;
queue<string> q;
unordered_map<string, int> d;
int dir[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
int bfs(string state)
{
q.push(state);
d[state] = 0;
string end = "12345678x";
while(!q.empty())
{
auto t = q.front();
q.pop();
int distance = d[t];
if (end == t) return distance;
int cor = t.find('x');
int x = cor / 3;
int y = cor % 3;
for (int i = 0; i < 4; i ++ )
{
int dx = x + dir[i][0];
int dy = y + dir[i][1];
if(dx >= 0 && dx < 3 && dy >= 0 && dy < 3)
{
swap(t[cor], t[dx * 3 + dy]);
if(!d.count(t))
{
d[t] = distance + 1;
q.push(t);
}
swap(t[cor], t[dx * 3 + dy]);
}
}
}
return -1;
}
int main()
{
char s[2]; // 用字符数组存储字符串时需要多开一位,用来存字符串的结束符'\0'
string start;
for (int i = 0; i < 9; i ++ )
{
cin >> s;
start += *s;
}
cout << bfs(start) << endl;
}
- 把一个字符串变成图中的一个节点
- 以后有空格的地方可以变成
标签:cor,int,++,数码,dx,dy,include 来源: https://www.cnblogs.com/WalterJ726/p/12694726.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。