pku2965 The Pilots Brothers' refrigerator
第一道双向广搜,188MS
题意:给定一个4X4的“+”“-”图,定义操作[i,j]为改变第i行和第j列的状态,输出使原图变为全“-”图的最小的操作数和各具体操作
#include <iostream>
using namespace std;
#define MAXN 2<<17
int r[5]={0,61440,3840,240,15};
int c[5]={0,34952,17476,8738,4369};
int rc[5][5]={
{0,0,0,0,0},
{0,32768,16384,8192,4096},
{0,2048,1024,512,256},
{0,128,64,32,16},
{0,8,4,2,1}
};
int open[MAXN],head,tail,mk[MAXN],st,ed,opera[MAXN],pre[MAXN],ans[MAXN],cnt;
char ss[6][6];
int change(int i,int j,int s){
int ns;
ns=~(r[i]^(~s));
ns=~(c[j]^(~ns));
ns=~(rc[i][j]^(~ns));
return ns;
}
void output(int s,int ns){
if(mk[s]==2){
int t=s;
s=ns;
ns=t;
}
while(s!=st){
ans[cnt++]=opera[s];
s=pre[s];
};
while(ns!=ed){
ans[cnt++]=opera[ns];
ns=pre[ns];
};
}
void solve(){
int i,j,s,ns;
if(st==ed){
printf("0\n");
return;
}
open[0]=st;
open[1]=ed;
mk[st]=1;
mk[ed]=2;
head=0;
tail=2;
while(head<tail){
s=open[head++];
for(i=1;i<=4;i++){
for(j=1;j<=4;j++){
ns=change(i,j,s);
if(!mk[ns]){
mk[ns]=mk[s];
opera[ns]=i*10+j;
pre[ns]=s;
open[tail++]=ns;
}
else{
if(mk[s]!=mk[ns]){
//cout<<"!!\n";
//printf("%d %d\n",i,j);
ans[cnt++]=i*10+j;
output(s,ns);
return;
}
}
}
}
}
return;
}
int main(){
cnt=0;
int i,j,k;
for(i=0;i<4;i++)
gets(ss[i]);
st=ed=0;
k=0;
//建立st的位图
for(i=3;i>=0;i--){
for(j=3;j>=0;j--){
if(ss[i][j]=='+')
st+=1<<k;
k++;
}
}
solve();
printf("%d\n",cnt);
for(i=0;i<cnt;i++)
printf("%d %d\n",ans[i]/10,ans[i]%10);
return 0;
}
using namespace std;
#define MAXN 2<<17
int r[5]={0,61440,3840,240,15};
int c[5]={0,34952,17476,8738,4369};
int rc[5][5]={
{0,0,0,0,0},
{0,32768,16384,8192,4096},
{0,2048,1024,512,256},
{0,128,64,32,16},
{0,8,4,2,1}
};
int open[MAXN],head,tail,mk[MAXN],st,ed,opera[MAXN],pre[MAXN],ans[MAXN],cnt;
char ss[6][6];
int change(int i,int j,int s){
int ns;
ns=~(r[i]^(~s));
ns=~(c[j]^(~ns));
ns=~(rc[i][j]^(~ns));
return ns;
}
void output(int s,int ns){
if(mk[s]==2){
int t=s;
s=ns;
ns=t;
}
while(s!=st){
ans[cnt++]=opera[s];
s=pre[s];
};
while(ns!=ed){
ans[cnt++]=opera[ns];
ns=pre[ns];
};
}
void solve(){
int i,j,s,ns;
if(st==ed){
printf("0\n");
return;
}
open[0]=st;
open[1]=ed;
mk[st]=1;
mk[ed]=2;
head=0;
tail=2;
while(head<tail){
s=open[head++];
for(i=1;i<=4;i++){
for(j=1;j<=4;j++){
ns=change(i,j,s);
if(!mk[ns]){
mk[ns]=mk[s];
opera[ns]=i*10+j;
pre[ns]=s;
open[tail++]=ns;
}
else{
if(mk[s]!=mk[ns]){
//cout<<"!!\n";
//printf("%d %d\n",i,j);
ans[cnt++]=i*10+j;
output(s,ns);
return;
}
}
}
}
}
return;
}
int main(){
cnt=0;
int i,j,k;
for(i=0;i<4;i++)
gets(ss[i]);
st=ed=0;
k=0;
//建立st的位图
for(i=3;i>=0;i--){
for(j=3;j>=0;j--){
if(ss[i][j]=='+')
st+=1<<k;
k++;
}
}
solve();
printf("%d\n",cnt);
for(i=0;i<cnt;i++)
printf("%d %d\n",ans[i]/10,ans[i]%10);
return 0;
}