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 |