搞了一个晚上,果然好久不写信息的后遗症。(辣鸡中考)
题目链接:https://www.luogu.org/problemnew/show/P2739
本质上就是曾经很拿手的深搜,但有一个很巧妙地贪心优化没有想到呐。
为了尽快的完成目标,白的只能往左走,黑的只能往右走。(不然就是往回走惹)
算是涨姿势了。。。
(谨以此代码,纪念我逝去的晚上与悼念我明天要崩的人机对话)
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=2000005;
string a;int flag=1;
map<string,int> m;
int n;int N=0;
string goal;
struct node
{
string k;int pos,fa,node,op;
};
node si[maxn];
node ans;int res[maxn];
queue<node> q;
int main()
{
scanf("%d",&n);string s="";
for(int i=1;i<=n;i++) {s=s+'W';goal=goal+'B';}
s=s+' ';goal=goal+' ';
for(int i=n+2;i<=2*n+1;i++) {s=s+'B';goal=goal+'W';}
node t;t.k=s;t.pos=n;m[t.k]=1;t.node=++N;
q.push(t);
while(!q.empty())
{
node tmp=q.front();q.pop();
if(tmp.pos>0&&tmp.k[tmp.pos-1]=='W')//这里是优化
{
node temp=tmp;
swap(temp.k[temp.pos],temp.k[temp.pos-1]);
temp.op=temp.pos-1;temp.pos-=1;temp.fa=tmp.node;temp.node=++N;si[N]=temp;
if(!m[temp.k]) {q.push(temp);m[temp.k]=1;}
if(temp.k==goal)
{
ans=temp;
break;
}
}
if(tmp.pos<2*n&&tmp.k[tmp.pos+1]=='B')
{
node temp=tmp;
swap(temp.k[temp.pos],temp.k[temp.pos+1]);
temp.op=temp.pos+1;temp.pos+=1;temp.fa=tmp.node;temp.node=++N;si[N]=temp;
if(!m[temp.k]) {q.push(temp);m[temp.k]=1;}
if(temp.k==goal)
{
ans=temp;
break;
}
}
if(tmp.pos>1&&tmp.k[tmp.pos-2]=='W')
{
node temp=tmp;
swap(temp.k[temp.pos],temp.k[temp.pos-2]);
temp.op=temp.pos-2;temp.pos-=2;temp.fa=tmp.node;temp.node=++N;si[N]=temp;
if(!m[temp.k]) {q.push(temp);m[temp.k]=1;}
if(temp.k==goal)
{
ans=temp;
break;
}
}
if(tmp.pos<2*n-1&&tmp.k[tmp.pos+2]=='B')
{
node temp=tmp;
swap(temp.k[temp.pos],temp.k[temp.pos+2]);
temp.op=temp.pos+2;temp.pos+=2;temp.fa=tmp.node;temp.node=++N;si[N]=temp;
if(!m[temp.k]) {q.push(temp);m[temp.k]=1;}
if(temp.k==goal)
{
ans=temp;
break;
}
}
}
int tot=0;
for(int i=ans.node;i!=1;i=si[i].fa)
{
res[++tot]=si[i].op+1;
}
int K=0;
for(int i=tot;i>=1;i--)
{
cout<<res[i]<<" ";K++;
if(K%20==0) cout<<endl;
}
cout<<endl;
return 0;
}