这道题目不难,但是有一个点需要注意:
题目需要输出所有方案中字典序最小的答案,一开始使用的双向BFS解决,但是
了三个点,原因是双向BFS搜索即使正向和反向同时按照字典序最小的顺序搜索,最后双向BFS搜索出来的结果也不一定是按照字典序最小的结果,为什么?因为双向扩展的异步性破坏了普通 BFS 的全局距离单调性
这是错误的双向
代码:
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
string start = "12345678", target = "";
string bfs(){
queue<string> q1, q2;
map<string, string> ma1, ma2;
q1.push(start);
q2.push(target);
ma1[start] = "", ma2[target] = "";
if(start == target) return "";
while(q1.size() && q2.size()){
if(q1.size() <= q2.size()){
int len = q1.size();
while(len --){
string ns = q1.front();
string nans = ma1[ns];
q1.pop();
string s1 = ns, ans1 = nans + "A";
reverse(s1.begin(), s1.end());
if(ma1.find(s1) == ma1.end()){
if(ma2.find(s1) != ma2.end()){
string fans1 = ans1, fans2 = ma2[s1];
reverse(fans2.begin(), fans2.end());
return fans1 + fans2;
}
else{
ma1[s1] = ans1;
q1.push(s1);
}
}
string s2 = ns[3] + ns.substr(0, 3) + ns.substr(5, 3) + ns[4], ans2 = nans + "B";
if(ma1.find(s2) == ma1.end()){
if(ma2.find(s2) != ma2.end()){
string fans1 = ans2, fans2 = ma2[s2];
reverse(fans2.begin(), fans2.end());
return fans1 + fans2;
}
else{
ma1[s2] = ans2;
q1.push(s2);
}
}
string s3 = ns, ans3 = nans + "C";
swap(s3[1], s3[2]), swap(s3[5], s3[6]), swap(s3[1], s3[5]);
if(ma1.find(s3) == ma1.end()){
if(ma2.find(s3) != ma2.end()){
string fans1 = ans3, fans2 = ma2[s3];
reverse(fans2.begin(), fans2.end());
return fans1 + fans2;
}
else{
ma1[s3] = ans3;
q1.push(s3);
}
}
}
}
else{
int len = q2.size();
while(len --){
string ns = q2.front();
string nans = ma2[ns];
q2.pop();
string s3 = ns, ans3 = nans + "C";
swap(s3[1], s3[5]), swap(s3[1], s3[2]), swap(s3[5], s3[6]);
if(ma2.find(s3) == ma2.end()){
if(ma1.find(s3) != ma1.end()){
string fans1 = ans3, fans2 = ma1[s3];
reverse(fans1.begin(), fans1.end());
return fans2 + fans1;
}
else{
ma2[s3] = ans3;
q2.push(s3);
}
}
string s2 = ns.substr(1, 3) + ns[0] + ns[7] + ns.substr(4, 3), ans2 = nans + "B";
if(ma2.find(s2) == ma2.end()){
if(ma1.find(s2) != ma1.end()){
string fans1 = ans2, fans2 = ma1[s2];
reverse(fans1.begin(), fans1.end());
return fans2 + fans1;
}
else{
ma2[s2] = ans2;
q2.push(s2);
}
}
string s1 = ns, ans1 = nans + "A";
reverse(s1.begin(), s1.end());
if(ma2.find(s1) == ma2.end()){
if(ma1.find(s1) != ma1.end()){
string fans1 = ans1, fans2 = ma1[s1];
reverse(fans1.begin(), fans1.end());
return fans2 + fans1;
}
else{
ma2[s1] = ans1;
q2.push(s1);
}
}
}
}
}
}
int main(){
HelloWorld;
for(int i = 1; i <= 8; i ++){
int x; cin >> x;
target += (x + '0');
}
string ans = bfs();
cout << ans.size() << endl;
for(int i = 0; i < (int)ans.size(); i ++){
cout << ans[i];
if((i + 1) % 60 == 0) cout << endl;
}
return 0;
}
这是正确的代码,就是普通的
#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
#define ll long long
#define IOS ios::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
#define HelloWorld IOS;
string start = "12345678", target = "";
string work1(string ss){
string s = ss;
reverse(s.begin(), s.end());
return s;
}
string work2(string ss){
string s = ss;
s = ss[3] + ss.substr(0, 3) + ss.substr(5, 3) + ss[4];
return s;
}
string work3(string ss){
string s = ss;
swap(s[1], s[2]);
swap(s[5], s[6]);
swap(s[1], s[5]);
return s;
}
string bfs(){
queue<string> q;
map<string, string> ma;
q.push(start);
ma[start] = "";
while(q.size()){
string ns = q.front();
string nans = ma[ns];
q.pop();
if(ns == target) return nans;
string s1 = work1(ns), ans1 = nans + "A";
if(ma.find(s1) == ma.end()){
ma[s1] = ans1;
q.push(s1);
}
string s2 = work2(ns), ans2 = nans + "B";
if(ma.find(s2) == ma.end()){
ma[s2] = ans2;
q.push(s2);
}
string s3 = work3(ns), ans3 = nans + "C";
if(ma.find(s3) == ma.end()){
ma[s3] = ans3;
q.push(s3);
}
}
}
int main(){
HelloWorld;
for(int i = 1; i <= 8; i ++){
int x; cin >> x;
target += (x + '0');
}
string ans = bfs();
cout << ans.size() << endl;
for(int i = 0; i < (int)ans.size(); i ++){
cout << ans[i];
if((i + 1) % 60 == 0) cout << endl;
}
return 0;
}



京公网安备 11010502036488号