282 lines
6.1 KiB
C++
282 lines
6.1 KiB
C++
#include <bits/stdc++.h>
|
|
using namespace std;
|
|
|
|
const int n = 20;
|
|
const int q_siz = 20;
|
|
const double keep_p = 0.97;
|
|
|
|
mt19937 mt(114514);
|
|
uniform_real_distribution<> d01(0, 1);
|
|
|
|
struct Question {
|
|
bitset<20> M[20];
|
|
int sx, sy, tx, ty, bx, by;
|
|
};
|
|
|
|
Question start_question;
|
|
|
|
namespace Solve {
|
|
bitset<20> mp[20];
|
|
int dis[20][20][20][20];
|
|
queue<tuple<int, int, int, int>> qu;
|
|
|
|
inline int bfs(int px, int py, int bx, int by, int tx, int ty) {
|
|
memset(dis, 127, sizeof(dis));
|
|
while (!qu.empty())
|
|
qu.pop();
|
|
|
|
auto expand = [&](int npx, int npy, int nbx, int nby, int d) {
|
|
if (npx < 0 || npx >= n)
|
|
return;
|
|
if (npy < 0 || npy >= n)
|
|
return;
|
|
if (nbx < 0 || nbx >= n)
|
|
return;
|
|
if (nby < 0 || nby >= n)
|
|
return;
|
|
if (mp[npx][npy] == 0)
|
|
return;
|
|
if (mp[nbx][nby] == 0)
|
|
return;
|
|
if (npx == nbx && npy == nby)
|
|
return;
|
|
|
|
if (dis[npx][npy][nbx][nby] <= d)
|
|
return;
|
|
dis[npx][npy][nbx][nby] = d;
|
|
qu.emplace(npx, npy, nbx, nby);
|
|
};
|
|
|
|
expand(px, py, bx, by, 0);
|
|
|
|
while (!qu.empty()) {
|
|
auto [npx, npy, nbx, nby] = qu.front();
|
|
int d = dis[npx][npy][nbx][nby];
|
|
qu.pop();
|
|
// cout<<"Now player at ( "<<npx<<" , "<<npy<<" ) and box at ( "<<nbx<<"
|
|
// , "<<nby<<" ) and dis = "<<d<<endl;
|
|
|
|
if (nbx == tx && nby == ty)
|
|
return d;
|
|
|
|
expand(npx + 1, npy, nbx, nby, d + 1);
|
|
expand(npx - 1, npy, nbx, nby, d + 1);
|
|
expand(npx, npy + 1, nbx, nby, d + 1);
|
|
expand(npx, npy - 1, nbx, nby, d + 1);
|
|
if (npx + 1 == nbx && npy == nby)
|
|
expand(npx + 1, npy, nbx + 1, nby, d + 1);
|
|
if (npx - 1 == nbx && npy == nby)
|
|
expand(npx - 1, npy, nbx - 1, nby, d + 1);
|
|
if (npx == nbx && npy + 1 == nby)
|
|
expand(npx, npy + 1, nbx, nby + 1, d + 1);
|
|
if (npx == nbx && npy - 1 == nby)
|
|
expand(npx, npy - 1, nbx, nby - 1, d + 1);
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
inline int solve(Question q) {
|
|
memcpy(mp, q.M, sizeof(q.M));
|
|
return bfs(q.sx, q.sy, q.bx, q.by, q.tx, q.ty);
|
|
}
|
|
}; // namespace Solve
|
|
|
|
vector<pair<Question, int>> prq, nwq;
|
|
|
|
inline void constructMain() {
|
|
auto expand = [&](Question q) {
|
|
if (q.sx < 0 || q.sx >= n)
|
|
return;
|
|
if (q.sy < 0 || q.sy >= n)
|
|
return;
|
|
if (q.bx < 0 || q.bx >= n)
|
|
return;
|
|
if (q.by < 0 || q.by >= n)
|
|
return;
|
|
if (q.tx < 0 || q.tx >= n)
|
|
return;
|
|
if (q.ty < 0 || q.ty >= n)
|
|
return;
|
|
if (q.M[q.sx][q.sy] == 0)
|
|
return;
|
|
if (q.M[q.bx][q.by] == 0)
|
|
return;
|
|
if (q.M[q.tx][q.ty] == 0)
|
|
return;
|
|
|
|
int d = Solve::solve(q);
|
|
nwq.push_back({q, d});
|
|
};
|
|
auto expandAll = [&](Question q) {
|
|
expand(q);
|
|
|
|
q.sx--;
|
|
expand(q);
|
|
q.sx++;
|
|
|
|
q.sx++;
|
|
expand(q);
|
|
q.sx--;
|
|
|
|
q.sy--;
|
|
expand(q);
|
|
q.sy++;
|
|
|
|
q.sy++;
|
|
expand(q);
|
|
q.sy--;
|
|
|
|
q.bx--;
|
|
expand(q);
|
|
q.bx++;
|
|
|
|
q.bx++;
|
|
expand(q);
|
|
q.bx--;
|
|
|
|
q.by--;
|
|
expand(q);
|
|
q.by++;
|
|
|
|
q.by++;
|
|
expand(q);
|
|
q.by--;
|
|
|
|
q.tx--;
|
|
expand(q);
|
|
q.tx++;
|
|
|
|
q.tx++;
|
|
expand(q);
|
|
q.tx--;
|
|
|
|
q.ty--;
|
|
expand(q);
|
|
q.ty++;
|
|
|
|
q.ty++;
|
|
expand(q);
|
|
q.ty--;
|
|
|
|
for (int i = 0; i < n; i++) {
|
|
for (int j = 0; j < n; j++) {
|
|
q.M[i][j] = !q.M[i][j];
|
|
expand(q);
|
|
q.M[i][j] = !q.M[i][j];
|
|
}
|
|
}
|
|
Question q1 = q;
|
|
for (int i = 0; i < n; i++) {
|
|
for (int j = 0; j < n; j++) {
|
|
int x = (d01(mt) <= 0.3);
|
|
q1.M[i][j] = q1.M[i][j] ^ x;
|
|
if ((i == q1.sx && j == q1.sy) || (i == q1.bx && j == q1.by)
|
|
|| (i == q1.tx && j == q1.ty))
|
|
q1.M[i][j] = 1;
|
|
}
|
|
}
|
|
expand(q1);
|
|
};
|
|
|
|
prq.push_back({start_question, Solve::solve(start_question)});
|
|
for (int _ = 1;; _++, swap(prq, nwq)) {
|
|
for (pair<Question, int> pr : prq)
|
|
expandAll(pr.first);
|
|
sort(nwq.begin(),
|
|
nwq.end(),
|
|
[&](const pair<Question, int>& a, const pair<Question, int>& b) {
|
|
return a.second > b.second;
|
|
});
|
|
vector<pair<Question, int>> tmp(0);
|
|
double nwpw = 1;
|
|
for (int i = 0; i < nwq.size(); i++) {
|
|
if (d01(mt) <= nwpw)
|
|
tmp.push_back(nwq[i]);
|
|
nwpw *= keep_p;
|
|
}
|
|
nwq = tmp;
|
|
|
|
if (_ % 1 == 0) {
|
|
cout << "Iterated for " << _ << " times" << endl;
|
|
Question mxq = nwq.front().first;
|
|
cout << "Max step = " << nwq.front().second << endl;
|
|
|
|
// cout<<"***************************"<<endl;
|
|
// for(int i=0;i<n;i++)
|
|
// {
|
|
// for(int j=0;j<n;j++)
|
|
// {
|
|
// if(i==mxq.sx&&j==mxq.sy) cout<<"P";
|
|
// else if(i==mxq.tx&&j==mxq.ty) cout<<"O";
|
|
// else if(i==mxq.bx&&j==mxq.by) cout<<"*";
|
|
// else if(mxq.M[i][j]==0) cout<<"#";
|
|
// else cout<<".";
|
|
// }
|
|
// cout<<endl;
|
|
// }
|
|
// cout<<"***************************"<<endl;
|
|
|
|
fstream fou("nowmax.txt", ios::out);
|
|
for (int i = 0; i < n; i++) {
|
|
for (int j = 0; j < n; j++) {
|
|
if (i == mxq.sx && j == mxq.sy)
|
|
fou << "P";
|
|
else if (i == mxq.tx && j == mxq.ty)
|
|
fou << "O";
|
|
else if (i == mxq.bx && j == mxq.by)
|
|
fou << "*";
|
|
else if (mxq.M[i][j] == 0)
|
|
fou << "#";
|
|
else
|
|
fou << ".";
|
|
}
|
|
fou << endl;
|
|
}
|
|
fou.close();
|
|
system("cp nowmax.txt nowmax-cp.txt");
|
|
}
|
|
}
|
|
}
|
|
|
|
inline void init() {
|
|
fstream fin("nowmax.txt", ios::in);
|
|
for (int i = 0; i < n; i++) {
|
|
string s;
|
|
fin >> s;
|
|
for (int j = 0; j < n; j++) {
|
|
if (s[j] == '#')
|
|
start_question.M[i][j] = 0;
|
|
else
|
|
start_question.M[i][j] = 1;
|
|
|
|
if (s[j] == 'P')
|
|
start_question.sx = i, start_question.sy = j;
|
|
if (s[j] == '*')
|
|
start_question.bx = i, start_question.by = j;
|
|
if (s[j] == 'O')
|
|
start_question.tx = i, start_question.ty = j;
|
|
}
|
|
}
|
|
// cout<<"Start question : *********************"<<endl;
|
|
// for(int i=0;i<n;i++)
|
|
// {
|
|
// for(int j=0;j<n;j++)
|
|
// {
|
|
// cout<<start_question.M[i][j];
|
|
// }
|
|
// cout<<endl;
|
|
// }
|
|
// cout<<"sx = "<<start_question.sx<<" , sy = "<<start_question.sy<<endl;
|
|
// cout<<"bx = "<<start_question.bx<<" , by = "<<start_question.by<<endl;
|
|
// cout<<"tx = "<<start_question.tx<<" , ty = "<<start_question.ty<<endl;
|
|
// cout<<"**************************************"<<endl;
|
|
fin.close();
|
|
}
|
|
|
|
int main() {
|
|
init();
|
|
|
|
// cout<<Solve::solve(start_question)<<endl;
|
|
|
|
constructMain();
|
|
} |