Logo Wy Online Judge

WyOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#402#60. 「NOIP2013」华容道ryp100278ms3692kbC++144.3kb2025-04-23 12:51:122025-04-23 12:51:13

answer


#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstring>
#include<queue>
#include<map>
#include<iostream>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
#define N 35
int rd()
{
	int f=1,s=0;char c=getchar();
	while(c<'0'||c>'9'){if(c=='-') f=-1;c=getchar();}
	while(c>='0'&&c<='9'){s=(s<<3)+(s<<1)+(c^48);c=getchar();}
	return f*s;
}
const int dx[]={1,-1,0,0},dy[]={0,0,1,-1};
//下上右左 
int n,m,q;
int mp[N][N];
int ex,ey,sx,sy,tx,ty;
int cnt[N][N][5];
bool check(int xx,int yy)
{
	if(xx<=0||xx>n||yy<=0||yy>m||mp[xx][yy]==0) return 0;
	return 1;
}
int tot;
struct node{
	int x,y,stp/*广搜的时候用 存步数*/;
};
bool vis[N][N],mark[N*N]/*spfa的标记数组*/;
vector<pair<int,int> >G[N*N];
void add(int u,int v,int w)
{
	G[u].push_back(make_pair(v,w));
}
int bfs(int ax,int ay,int bx,int by,int cx,int cy)
{//a到b不经过点c的最短距离 
	if(ax==bx&&ay==by) return 0;//起点就是终点
	memset(vis,0,sizeof(vis)); 
	queue<node>Q;
	while(!Q.empty()) Q.pop();
	node s;s.x=ax,s.y=ay,s.stp=0;
	Q.push(s);
	vis[ax][ay]=1;
	while(!Q.empty())
	{
		node now=Q.front();Q.pop();
		if(now.x==bx&&now.y==by) return now.stp;
		for(int i=0;i<4;i++)
		{
			node nxt;
			nxt.x=now.x+dx[i],nxt.y=now.y+dy[i];
			if(!check(nxt.x,nxt.y)) continue;
			if(nxt.x==cx&&nxt.y==cy) continue;
			if(vis[nxt.x][nxt.y]) continue;
			nxt.stp=now.stp+1;
			Q.push(nxt);
			vis[nxt.x][nxt.y]=1;
		}
	}
	return INF;//不能到达 
}
void Init()
{
	//cnt存状态标号 spfa的时候是把点看成状态 用边来表示状态的转移 
	//[i][j][k]是表示开始的那个点的坐标是(i,j) 空格在它的k方向 
	tot=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int k=0;k<4;k++)
				if(mp[i][j]&&check(i+dx[k],j+dy[k]))
					cnt[i][j][k]=++tot;//给状态标号 没有标号的就是不可行的状态 
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int k=0;k<4;k++)
				if(cnt[i][j][k])
				{
					int tmp;
					if(k==0) tmp=1;
					if(k==1) tmp=0;
					if(k==2) tmp=3;
					if(k==3) tmp=2;
					add(cnt[i][j][k],cnt[i+dx[k]][j+dy[k]][tmp],1);
					//连单向边就可以了 后面会遍历到旁边状态连回来的
					//交换空白格子和起点格子 只需要一步  
				}
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int k=0;k<4;k++)
				for(int p=0;p<4;p++)//枚举起点格子相邻一圈的两个格子 
					if(k!=p&&cnt[i][j][k]&&cnt[i][j][p])
						add(cnt[i][j][k],cnt[i][j][p],bfs(i+dx[k],j+dy[k],i+dx[p],j+dy[p],i,j));
	//可以起点格子不动 而空白格子绕着它转(换方向)
	//如果用起点格子自己换方向 可能没那么优秀因为要绕一绕 
	//而且起点格子有可能会跑到一个离终点的地方去了 更不优 
	//而只动空白格子可能会优秀一些 因为空白格子最优(到处都是活动格子)只用走2~4步 
	
	//经过其他格子没有任何影响 因为都是1 只是空白格子变了而已
	//而经过起点格子则会改变起点格子的坐标 
}
int dis[N*N];
int spfa()
{
	queue<int>Q;
	while(!Q.empty()) Q.pop();
	if(sx==tx&&sy==ty) return 0;
	memset(dis,INF,sizeof(dis));
	memset(mark,0,sizeof(mark));
	for(int k=0;k<4;k++)
	{//空格先走到起点的四周 初始状态 以空格从起点四周开始 
		if(cnt[sx][sy][k])
		{
			dis[cnt[sx][sy][k]]=bfs(ex,ey,sx+dx[k],sy+dy[k],sx,sy);
			Q.push(cnt[sx][sy][k]);
			mark[cnt[sx][sy][k]]=1; 
		}
	}
	while(!Q.empty())
	{
		int u=Q.front();Q.pop();
		mark[u]=0;
		for(int i=0;i<G[u].size();i++)
		{
			int v=G[u][i].first,w=G[u][i].second;
			if(dis[v]>dis[u]+w)
			{
				dis[v]=dis[u]+w;
				if(!mark[v])
				{
					Q.push(v);
					mark[v]=1;
				}
			}
		}
	}
	//空格在哪里不用管 起点格子到了就可以 
	//从空格在起点格子四周随便哪个地方的状态到空格在终点格子四周随便哪个地方的状态
	int res=INF;
	for(int k=0;k<4;k++)
		if(cnt[tx][ty][k])
			res=min(res,dis[cnt[tx][ty][k]]);
	if(res==INF) return -1;//走不到
	return res; 	
}
int main() 
{
	n=rd(),m=rd(),q=rd();
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			mp[i][j]=rd();
	Init();
	while(q--)
	{
		ex=rd(),ey=rd(),sx=rd(),sy=rd(),tx=rd(),ty=rd();
		printf("%d\n",spfa());
	}
	return 0;
}

Details

小提示:点击横条可展开更详细的信息

Test #1:

score: 5
Accepted
time: 1ms
memory: 3336kb

input:

3 3 1
1 1 0
1 1 0
1 1 0
3 1 1 1 3 1

output:

7

result:

ok 1 number(s): "7"

Test #2:

score: 5
Accepted
time: 4ms
memory: 3400kb

input:

5 5 1
1 1 1 1 1
1 1 1 1 1
1 0 1 1 1
1 1 1 1 1
1 0 1 0 1
4 2 3 4 2 2

output:

13

result:

ok 1 number(s): "13"

Test #3:

score: 5
Accepted
time: 4ms
memory: 3532kb

input:

10 10 1
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 1 0 0 0
1 0 1 1 1 0 1 1 1 1
1 0 1 0 1 0 1 0 1 0
1 0 1 1 1 0 ...

output:

377

result:

ok 1 number(s): "377"

Test #4:

score: 5
Accepted
time: 3ms
memory: 3520kb

input:

3 3 1
0 1 1
1 1 0
1 1 1
2 1 3 1 1 3

output:

-1

result:

ok 1 number(s): "-1"

Test #5:

score: 5
Accepted
time: 3ms
memory: 3580kb

input:

5 5 1
1 1 1 1 1
1 1 1 1 1
0 1 1 0 1
0 1 1 1 1
1 1 0 1 1
2 4 1 1 4 2

output:

17

result:

ok 1 number(s): "17"

Test #6:

score: 5
Accepted
time: 3ms
memory: 3536kb

input:

10 10 1
1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 1 0 0 0
1 0 1 1 1 0 1 1 1 0
1 0 1 0 1 0 1 0 1 0
1 0 1 0 1 0 ...

output:

227

result:

ok 1 number(s): "227"

Test #7:

score: 5
Accepted
time: 2ms
memory: 3360kb

input:

10 20 5
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
1 1 1 1 1 1 ...

output:

1176
2279
44
1525
493

result:

ok 5 number(s): "1176 2279 44 1525 493"

Test #8:

score: 5
Accepted
time: 9ms
memory: 3556kb

input:

20 25 5
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

output:

15257
1418
2345
2025
6189

result:

ok 5 number(s): "15257 1418 2345 2025 6189"

Test #9:

score: 5
Accepted
time: 20ms
memory: 3528kb

input:

30 30 10
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...

output:

71934
50048
77876
36822
3122
80641
-1
64554
65906
10638

result:

ok 10 numbers

Test #10:

score: 5
Accepted
time: 4ms
memory: 3480kb

input:

10 20 5
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 0
1 0 1 1 1 0 ...

output:

3060
3482
134
1288
-1

result:

ok 5 number(s): "3060 3482 134 1288 -1"

Test #11:

score: 5
Accepted
time: 4ms
memory: 3660kb

input:

20 25 5
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

output:

2638
13168
9091
12092
8525

result:

ok 5 number(s): "2638 13168 9091 12092 8525"

Test #12:

score: 5
Accepted
time: 17ms
memory: 3520kb

input:

30 30 10
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0...

output:

40970
-1
-1
20106
34048
21854
24476
-1
29970
15139

result:

ok 10 numbers

Test #13:

score: 5
Accepted
time: 11ms
memory: 3428kb

input:

10 20 400
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
1 0 1 1 1 ...

output:

1123
2979
3325
3580
3564
0
610
2931
2901
392
2959
2795
3118
3275
2267
157
2591
2070
3845
307
1553
10...

result:

ok 400 numbers

Test #14:

score: 5
Accepted
time: 18ms
memory: 3620kb

input:

20 25 450
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

output:

5813
-1
8039
10811
7533
7569
5511
-1
5270
11074
10284
1274
10828
7308
13396
-1
10352
-1
1094
-1
-1
1...

result:

ok 450 numbers

Test #15:

score: 5
Accepted
time: 34ms
memory: 3468kb

input:

30 30 500
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

output:

45430
42629
11500
34698
39003
3846
23838
59458
51409
58852
6824
2903
30391
3170
18108
19900
9158
770...

result:

ok 500 numbers

Test #16:

score: 5
Accepted
time: 35ms
memory: 3692kb

input:

30 30 500
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

output:

15504
45201
15725
-1
64549
-1
29634
14906
10102
39160
-1
7295
68621
14617
-1
5325
65849
47760
5322
2...

result:

ok 500 numbers

Test #17:

score: 5
Accepted
time: 7ms
memory: 3480kb

input:

10 20 400
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
1 0 1 1 1 ...

output:

1788
1997
2144
479
1241
792
2644
913
0
2956
-1
183
1358
2995
290
1082
1074
931
2962
2025
2211
1098
2...

result:

ok 400 numbers

Test #18:

score: 5
Accepted
time: 24ms
memory: 3444kb

input:

20 25 450
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 ...

output:

2293
1107
227
4219
3227
4357
2254
5891
1300
-1
4163
2056
140
3164
-1
1750
2859
8118
1136
4098
3919
4...

result:

ok 450 numbers

Test #19:

score: 5
Accepted
time: 36ms
memory: 3596kb

input:

30 30 500
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...

output:

6667
68635
16685
34236
66264
109
15972
12341
21211
7009
45547
29642
36831
7554
7186
36934
37614
2593...

result:

ok 500 numbers

Test #20:

score: 5
Accepted
time: 39ms
memory: 3468kb

input:

30 30 500
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 ...

output:

45435
36968
37705
15892
-1
45171
21764
19862
17735
330
44118
1999
-1
2643
8296
22118
24881
2899
1833...

result:

ok 500 numbers