正解:状压
解题报告:
先,放下传送门QwQ
说真的我jio得这题不管是思路还是实现上,都还是有一定难度的?然后就看到神仙hl博客里一句"太水了不讲了"就过掉了,,,好的趴太强辽QAQ
但是这题我开始是真的没想到状压,,,知道状压之后实现代码实现了好久,,,看来灵巧是真的菜趴QAQ
然后就讲下这题QwQ
首先这题,一眼bfs板子题嘛,大体的框架应该都还是想得出来的
但是如果!你和sd灵巧想到了一个路子上!直接存的矩阵!你就可以获得10pts的好成绩,,,显然会MLE的啊喂!
然后就考虑,它不是只有01嘛,显然状压鸭!
然后照理来说就做完了
然而sd灵巧代码实现能力太差了,,,打了俩小时死活调不出来,,,就放弃了,拿的hl的代码改了下过的(但改动挺大的我jio得,比他代码好看多了2333333
然后另外注意一下还用了俩优化(不过似乎不用也能A?
一个是双向搜索,通过beg和tail实现的
另一个是显然的一个结论,就是对于俩俩交换你只用搜和左边交换和上边交换,和右和下的显然会被别的格子枚举到,就可以/2了(也没快多少的说QAQ
没了,放下代码就跑了!
#include<bits/stdc++.h> using namespace std; #define rg register #define ll int #define mp make_pair #define rp(i,x,y) for(rg ll i=x;i<=y;++i) #define my(i,x,y) for(rg ll i=x;i>=y;--i) const ll N=70000; ll beg[N],tail[N],ans,temp[5][5],dx[]={0,1,0},dy[]={0,0,1},t1; queue< ll > q; inline void frhash(int x){my(i,4,1)my(j,4,1){temp[i][j]=x&1;x>>=1;}} inline int tohash(){int ret=0;rp(i,1,4)rp(j,1,4){ret<<=1;ret|=temp[i][j];}return ret;} inline bool jde(int x,int y){return x<5 && y<5 && x>0 && y>0;} inline int bfs(void) { while(!q.empty()) { int now=q.front(),tp=0;frhash(now);q.pop(); rp(i,1,4) rp(j,1,4) rp(k,1,2) if(jde(i+dx[k],j+dy[k])) { swap(temp[i][j],temp[i+dx[k]][j+dy[k]]);tp=tohash(); if(beg[tp] && tail[tp])return beg[tp]+tail[tp]-2; if(beg[now] && (!beg[tp]))beg[tp]=beg[now]+1,q.push(tp); if(tail[now] && (!tail[tp]))tail[tp]=tail[now]+1,q.push(tp); swap(temp[i][j],temp[i+dx[k]][j+dy[k]]); } } } int main() { rp(t,1,4)rp(i,1,4)scanf("%1d",&temp[t][i]);t1=tohash();beg[t1]=1;q.push(t1); rp(t,1,4)rp(i,1,4)scanf("%1d",&temp[t][i]);t1=tohash();tail[t1]=1;q.push(t1); cout<<bfs()<<endl; return 0; }