| Task: | Klotski |
| Sender: | Game of Nolife |
| Submission time: | 2017-05-27 14:16:37 +0300 |
| Language: | C++ |
| Status: | READY |
| Result: | ACCEPTED |
| test | verdict | time | |
|---|---|---|---|
| #1 | ACCEPTED | 0.15 s | details |
| #2 | ACCEPTED | 0.10 s | details |
| #3 | ACCEPTED | 0.04 s | details |
| #4 | ACCEPTED | 0.12 s | details |
| #5 | ACCEPTED | 0.12 s | details |
| #6 | ACCEPTED | 0.05 s | details |
| #7 | ACCEPTED | 0.06 s | details |
| #8 | ACCEPTED | 0.06 s | details |
| #9 | ACCEPTED | 0.04 s | details |
| #10 | ACCEPTED | 0.03 s | details |
| #11 | ACCEPTED | 0.07 s | details |
| #12 | ACCEPTED | 0.12 s | details |
Code
#include <bits/stdc++.h>
#define F first
#define S second
#define X real()
#define Y imag()
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> pii;
string grid[5];
struct state {
pii xloc;
pii eloc;
pii adloc[4];
pii filoc[4];
state() {
}
state(pii xx, pii ee, pii* ad, pii* fi) : xloc(xx), eloc(ee) {
for (int i=0;i<4;i++) {
adloc[i]=ad[i];
filoc[i]=fi[i];
}
sort(adloc,adloc+4);
sort(filoc,filoc+4);
}
bool isSolved() {
if (xloc.F == 3 && xloc.S == 1) return true;
return false;
}
bool operator==(const state& ref) const {
if (xloc!=ref.xloc) return false;
if (eloc!=ref.eloc) return false;
for (int i=0;i<4;i++) {
if (adloc[i]!=ref.adloc[i]) return false;
if (filoc[i]!=ref.filoc[i]) return false;
}
return true;
}
bool operator<(const state& ref) const {
if (xloc!=ref.xloc) return xloc<ref.xloc;
if (eloc!=ref.eloc) return eloc<ref.eloc;
for (int i=0;i<4;i++) {
if (adloc[i]!=ref.adloc[i]) return adloc[i]<ref.adloc[i];
if (filoc[i]!=ref.filoc[i]) return filoc[i]<ref.filoc[i];
}
return false;
}
bool isFree(int i, int j) {
if (i<0 || i>=5) return false;
if (j<0 || j>=4) return false;
if (xloc.F == i || xloc.F == i-1) {
if (xloc.S == j || xloc.S == j-1) return false;
}
if (eloc.F == i) {
if (eloc.S == j || eloc.S == j-1) return false;
}
for (int ii=0;ii<4;ii++) {
if (adloc[ii].F == i || adloc[ii].F == i-1) {
if (adloc[ii].S == j) return false;
}
if (filoc[ii].F == i && filoc[ii].S == j) return false;
}
return true;
}
int blockInd(int i, int j) {
if (i<0 || i>=5) return -1;
if (j<0 || j>=4) return -1;
if (xloc.F == i || xloc.F == i-1) {
if (xloc.S == j || xloc.S == j-1) return 10;
}
if (eloc.F == i) {
if (eloc.S == j || eloc.S == j-1) return 5;
}
for (int ii=0;ii<4;ii++) {
if (adloc[ii].F == i || adloc[ii].F == i-1) {
if (adloc[ii].S == j) return ii+1;
}
if (filoc[ii].F == i && filoc[ii].S == j) return ii+6;
}
return -1;
}
bool checkCell(int i, int j, int block) {
// cout<<isFree(i,j)<<" "<<blockInd(i,j)<<endl;
if (isFree(i,j) || blockInd(i,j)==block) return true;
return false;
}
bool canMove(int block, pii dir) {
if (block==10) {
if (!checkCell(xloc.F+dir.F,xloc.S+dir.S,block)) return false;
if (!checkCell(xloc.F+dir.F+1,xloc.S+dir.S,block)) return false;
if (!checkCell(xloc.F+dir.F,xloc.S+dir.S+1,block)) return false;
if (!checkCell(xloc.F+dir.F+1,xloc.S+dir.S+1,block)) return false;
} else if (block==5) {
if (!checkCell(eloc.F+dir.F,eloc.S+dir.S,block)) return false;
if (!checkCell(eloc.F+dir.F,eloc.S+dir.S+1,block)) return false;
} else if (block<5) {
if (!checkCell(adloc[block-1].F+dir.F,adloc[block-1].S+dir.S,block)) return false;
if (!checkCell(adloc[block-1].F+dir.F+1,adloc[block-1].S+dir.S,block)) return false;
} else {
if (!checkCell(filoc[block-6].F+dir.F,filoc[block-6].S+dir.S,block)) return false;
}
return true;
}
state move(int block, pii dir) {
state s(xloc,eloc,adloc,filoc);
if (block==10) {
s.xloc.F+=dir.F;
s.xloc.S+=dir.S;
} else if (block==5) {
s.eloc.F+=dir.F;
s.eloc.S+=dir.S;
} else if (block<5) {
s.adloc[block-1].F+=dir.F;
s.adloc[block-1].S+=dir.S;
} else {
s.filoc[block-6].F+=dir.F;
s.filoc[block-6].S+=dir.S;
}
sort(s.adloc,s.adloc+4);
sort(s.filoc,s.filoc+4);
return s;
}
};
void printState(state pri) {
for (int i=0;i<5;i++) {
for (int j=0;j<4;j++) {
int block=pri.blockInd(i,j);
if (block==-1) cout<<".";
else if (block==10) cout<<"X";
else cout<<(char)(block+'A'-1);
}
cout<<endl;
}
}
pair<bool,state> moveBlock(state current, int block, pii dir) {
// printState(current);
// cout<<block<<" "<<dir.F<<" "<<dir.S<<endl;
if (block==-1) return {false,current};
// cout<<block<<" "<<dir.F<<" "<<dir.S<<endl;
if (!current.canMove(block,dir)) return {false,current};
// cout<<block<<" "<<dir.F<<" "<<dir.S<<endl;
return {true,current.move(block,dir)};
}
pii aadd[4];
pii ffii[4];
int bfs(state start) {
// printState(start);
set<state> visited;
vector<pair<state,int>> toHandle;
toHandle.push_back({start,0});
visited.insert(start);
for (unsigned int ii=0;ii<toHandle.size();ii++) {
// cout<<ii<<endl;
if (toHandle[ii].F.isSolved()) return toHandle[ii].S;
state cur=toHandle[ii].F;
for (int i=0;i<5;i++) {
for (int j=0;j<4;j++) {
if (cur.isFree(i,j)) {
for (int i2=-1;i2<=1;i2++) {
for (int j2=-1;j2<=1;j2++) {
if (i2*j2==0 && abs(i2+j2)==1) {
auto z = moveBlock(cur,cur.blockInd(i+i2,j+j2),{-i2,-j2});
// cout<<"bfs "<<z.F<<" "<<visited.count(z.S)<<endl;
// cout<<visited.size()<<endl;
if (z.F && !visited.count(z.S)) {
visited.insert(z.S);
toHandle.push_back({z.S,toHandle[ii].S+1});
// cout<<"---"<<endl;
// printState(z.S);
// cout<<"---"<<endl;
}
}
}
}
}
}
}
// return -1;
}
return -1;
}
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
for (int i=0;i<5;i++) cin>>grid[i];
map<char,pii> loc;
for (int i=0;i<5;i++) {
for (int j=0;j<4;j++) {
if (grid[i][j]!='.' && !loc.count(grid[i][j])) {
loc[grid[i][j]]={i,j};
}
}
}
for (char c='A';c<='D';c++) aadd[c-'A']=loc[c];
for (char c='F';c<='I';c++) ffii[c-'F']=loc[c];
state starting(loc['X'],loc['E'],aadd,ffii);
cout<<bfs(starting)<<"\n";
}Test details
Test 1
Verdict: ACCEPTED
| input |
|---|
| AXXC AXXC BEED BGHD F..I |
| correct output |
|---|
| 116 |
| user output |
|---|
| 116 |
Test 2
Verdict: ACCEPTED
| input |
|---|
| XXAB XXAB CDEE CDFG HI.. |
| correct output |
|---|
| 104 |
| user output |
|---|
| 104 |
Test 3
Verdict: ACCEPTED
| input |
|---|
| XXEE XXAB CDAB CDFG HI.. |
| correct output |
|---|
| 35 |
| user output |
|---|
| 35 |
Test 4
Verdict: ACCEPTED
| input |
|---|
| XXFG XXAB CDAB CDEE HI.. |
| correct output |
|---|
| 79 |
| user output |
|---|
| 79 |
Test 5
Verdict: ACCEPTED
| input |
|---|
| XXFG XXAB CDAB CDHI EE.. |
| correct output |
|---|
| 70 |
| user output |
|---|
| 70 |
Test 6
Verdict: ACCEPTED
| input |
|---|
| FGHI AXXB AXXB CEED C..D |
| correct output |
|---|
| -1 |
| user output |
|---|
| -1 |
Test 7
Verdict: ACCEPTED
| input |
|---|
| FGHI AEEB AXXB CXXD C..D |
| correct output |
|---|
| 1 |
| user output |
|---|
| 1 |
Test 8
Verdict: ACCEPTED
| input |
|---|
| FGHI AEEB A..B CXXD CXXD |
| correct output |
|---|
| 0 |
| user output |
|---|
| 0 |
Test 9
Verdict: ACCEPTED
| input |
|---|
| FXXG AXXB AEEB .CD. HCDI |
| correct output |
|---|
| -1 |
| user output |
|---|
| -1 |
Test 10
Verdict: ACCEPTED
| input |
|---|
| EECD FGCD ..HI BAXX BAXX |
| correct output |
|---|
| 5 |
| user output |
|---|
| 5 |
Test 11
Verdict: ACCEPTED
| input |
|---|
| ..CD FGCD EEHI BAXX BAXX |
| correct output |
|---|
| 15 |
| user output |
|---|
| 15 |
Test 12
Verdict: ACCEPTED
| input |
|---|
| FXXG CXXD CABD HABI .EE. |
| correct output |
|---|
| 100 |
| user output |
|---|
| 100 |
