4
19
2016
0

[BZOJ1085] [SCOI2005]骑士精神

双向BFS

怎么写着写着就5kb+了呢……其他人为什么跑得那么快……

#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

const int Smod=9973;
const pair<int,int> tab[]={make_pair(-1,-2),make_pair(-2,-1),make_pair(-1,2),make_pair(-2,1),make_pair(1,-2),make_pair(2,-1),make_pair(1,2),make_pair(2,1)};
const long long Lmod1=233333333333333ll,Lmod2=666666666666667ll;

int T,hn1,hn2,mat[10][10],h1[10005],h2[10005];
char mt[10][10];

struct Hash{
int next,step;
long long L1,L2;
}ha1[1000005],ha2[1000005];

void AddHash1(int s,long long l1,long long l2,int step){
ha1[++hn1].L1=l1;
ha1[hn1].L2=l2;
ha1[hn1].step=step;
ha1[hn1].next=h1[s];
h1[s]=hn1;
}

int FindHash1(int s,long long l1,long long l2){
for(int i=h1[s];i;i=ha1[i].next){
	if(ha1[i].L1==l1 && ha1[i].L2==l2)return i;
}
return 0;
}

void AddHash2(int s,long long l1,long long l2,int step){
ha2[++hn2].L1=l1;
ha2[hn2].L2=l2;
ha2[hn2].step=step;
ha2[hn2].next=h2[s];
h2[s]=hn2;
}

int FindHash2(int s,long long l1,long long l2){
for(int i=h2[s];i;i=ha2[i].next){
	if(ha2[i].L1==l1 && ha2[i].L2==l2)return i;
}
return 0;
}

struct Matrix{
int mt[6][6],now;
friend bool operator==(Matrix A,Matrix B){
for(int i=1;i<=5;i++){
	for(int j=1;j<=5;j++)if(A.mt[i][j]!=B.mt[i][j])return 0;
}
return 1;
}
}Template;

pair<int,pair<long long,long long> > GetHash(Matrix M){
int s=0;
long long l1=0,l2=0;
for(int i=1;i<=5;i++){
	for(int j=1;j<=5;j++){
		s=(s*127+M.mt[i][j])%Smod;
		l1=(l1*233+M.mt[i][j])%Lmod1;
		l2=(l2*667+M.mt[i][j])%Lmod2;
	}
}
return make_pair(s,make_pair(l1,l2));
}

queue<Matrix> Q1,Q2;

void OutMatrix(Matrix M){
puts("This is Mt:");
for(int i=1;i<=5;i++){
	for(int j=1;j<=5;j++){
		printf("%d",M.mt[i][j]);
	}
	putchar('\n');
}
puts("-------------");
}

void BFS(int mode,int st){
if(st>8){puts("-1");return;}
if(mode){
	while(Q1.front().now==st){
		Matrix u=Q1.front();
		//OutMatrix(u);
		Q1.pop();
		int x,y;
		for(x=1;x<=5;x++){for(y=1;y<=5;y++){if(!u.mt[x][y])break;}if(!u.mt[x][y] && y<6)break;}
		//printf("XY:%d %d\n",x,y);
		for(int i=0;i<8;i++){
			int px=x+tab[i].first,py=y+tab[i].second,tc;
			if(px<1 || py<1 || px>5 || py>5)continue;
			swap(u.mt[x][y],u.mt[px][py]);u.now++;
			pair<int,pair<long long,long long> >Pt=GetHash(u);
			tc=FindHash2(Pt.first,Pt.second.first,Pt.second.second);
			if(tc){printf("%d\n",u.now+ha2[tc].step<=15?u.now+ha2[tc].step:-1);return;}
			tc=FindHash1(Pt.first,Pt.second.first,Pt.second.second);
			if(!tc){AddHash1(Pt.first,Pt.second.first,Pt.second.second,u.now);Q1.push(u);}
			swap(u.mt[x][y],u.mt[px][py]);u.now--;
		}
	}
    BFS(mode^1,st);
    return;
}
else {
	while(Q2.front().now==st){
		Matrix u=Q2.front();
		//OutMatrix(u);
		Q2.pop();
		int x,y;
		for(x=1;x<=5;x++){for(y=1;y<=5;y++){if(!u.mt[x][y])break;}if(!u.mt[x][y] && y<6)break;}
		//printf("XY:%d %d\n",x,y);
		for(int i=0;i<8;i++){
			int px=x+tab[i].first,py=y+tab[i].second,tc;
			if(px<1 || py<1 || px>5 || py>5)continue;
			swap(u.mt[x][y],u.mt[px][py]);u.now++;
			pair<int,pair<long long,long long> >Pt=GetHash(u);
			tc=FindHash1(Pt.first,Pt.second.first,Pt.second.second);
			if(tc){printf("%d\n",u.now+ha1[tc].step<=15?u.now+ha1[tc].step:-1);return;}
			tc=FindHash2(Pt.first,Pt.second.first,Pt.second.second);
			if(!tc){AddHash2(Pt.first,Pt.second.first,Pt.second.second,u.now);Q2.push(u);}
			swap(u.mt[x][y],u.mt[px][py]);u.now--;
		}
	}
    BFS(mode^1,st+1);
    return;
}
}

void MakeMt(Matrix &x){
for(int i=1;i<=5;i++){
	for(int j=1;j<=5;j++){
		x.mt[i][j]=mat[i][j];
	}
}
x.now=0;
}

void Prepare(){
mat[1][1]=2;mat[1][2]=2;mat[1][3]=2;mat[1][4]=2;mat[1][5]=2;
mat[2][1]=1;mat[2][2]=2;mat[2][3]=2;mat[2][4]=2;mat[2][5]=2;
mat[3][1]=1;mat[3][2]=1;mat[3][3]=0;mat[3][4]=2;mat[3][5]=2;
mat[4][1]=1;mat[4][2]=1;mat[4][3]=1;mat[4][4]=1;mat[4][5]=2;
mat[5][1]=1;mat[5][2]=1;mat[5][3]=1;mat[5][4]=1;mat[5][5]=1;
}

void First(){
while(!Q1.empty())Q1.pop();
while(!Q2.empty())Q2.pop();
memset(h1,0,sizeof(h1));
memset(h2,0,sizeof(h2));
hn1=0;hn2=0;
}

int main(){
freopen("1085.in","r",stdin);
freopen("1085.out","w",stdout);
scanf("%d",&T);
Prepare();
MakeMt(Template);
while(T--){
	First();
	scanf("%s %s %s %s %s",mt[1]+1,mt[2]+1,mt[3]+1,mt[4]+1,mt[5]+1);
    for(int i=1;i<=5;i++){
		for(int j=1;j<=5;j++){
			if(mt[i][j]=='0')mat[i][j]=1;
			else if(mt[i][j]=='1')mat[i][j]=2;
			else mat[i][j]=0;
		}
    }
    Matrix Tp;
    pair<int,pair<long long,long long> > Pr;
    MakeMt(Tp);
    if(Tp==Template){puts("0");continue;}
    Q1.push(Tp);
    Q2.push(Template);
    Pr=GetHash(Tp);
    AddHash1(Pr.first,Pr.second.first,Pr.second.second,0);
    Pr=GetHash(Template);
    AddHash2(Pr.first,Pr.second.first,Pr.second.second,0);
    BFS(1,0);
}
return 0;
}
Category: BZOJ | Tags: OI bzoj | Read Count: 281

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter

Host by is-Programmer.com | Power by Chito 1.3.3 beta | Theme: Aeros 2.0 by TheBuckmaker.com