noip2013 华容道
Posted A_LEAF
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了noip2013 华容道相关的知识,希望对你有一定的参考价值。
solution
暴力(70):
定义f[x1][y1][x2][y2]为空格在(x1,y1),目标棋子在(x2,y2),时的最小步数
之后bfs就行
正解:
也是bfs
预处理出来数组 g[x][y][k][kk] 1<=k,kk<=4
意义是 当前棋子在(x,y)白棋子在k方向(上下左右),想要走到kk方向的最小步数
之后对于每次询问
首先把白格子挪到目标旗子周围,之后把目标棋子挪到目标位置,bfs利用g[][][][]数组
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<queue> 5 #define mem(a,b) memset(a,b,sizeof(a)) 6 using namespace std; 7 const int DUI=20000006; 8 const int INF=0x7fffffff; 9 10 inline int minn(int a,int b){return a<b?a:b;} 11 12 struct Queue 13 { 14 int x,y; 15 }; 16 17 queue<Queue> q; 18 int n,m,Q,qqq; 19 int bx[6]={0,-1,1,0,0,0}; 20 int by[6]={0,0,0,-1,1,0};// 1 上 2 下 3 左 4 右 21 int f[36][36][6],ha[6],flag[36][36],vis[36][36][6]; 22 int a[36][36],g[36][36][6][6],d[36][36]; 23 int whx,why,sx,sy,tx,ty; 24 25 void out11(); 26 27 void chu() 28 { 29 mem(g,60); 30 qqq=g[0][0][0][0]; 31 Queue now; 32 int x,y; 33 for(int i=1;i<=n;++i) 34 for(int j=1;j<=m;++j) 35 { 36 if(a[i][j]==0) 37 continue; 38 for(int bai=1;bai<=4;++bai) 39 {//printf("saafsffas\n"); 40 if( (i+bx[bai]<1) || (i+bx[bai]>n) || (j+by[bai]<1) || (j+by[bai]>m) || (a[i+bx[bai]][j+by[bai]]==0) ) 41 continue; 42 for(int tt=1;tt<=4;++tt) 43 { 44 if( (i+bx[tt]<1) || (i+bx[tt]>n) || (j+by[tt]<1) || (j+by[tt]>m) || (a[i+bx[tt]][j+by[tt]]==0) ) 45 continue; 46 //printf("i=%d j=%d\n",i,j); 47 if(bai==tt) 48 { 49 g[i][j][bai][tt]=0; 50 continue; 51 } 52 53 54 55 while(!q.empty())q.pop(); 56 mem(d,60);mem(flag,0); 57 sx=i+bx[bai];sy=j+by[bai]; 58 tx=i+bx[tt];ty=j+by[tt]; 59 d[sx][sy]=0;flag[sx][sy]=1; 60 q.push((Queue){sx,sy}); 61 while(!q.empty()) 62 { 63 64 now=q.front();q.pop(); 65 x=now.x;y=now.y;flag[x][y]=0; 66 //if(x==tx&&y==ty) 67 // break; 68 69 for(int k=1;k<=4;++k) 70 { 71 if(x+bx[k]<1||x+bx[k]>n||y+by[k]<1||y+by[k]>m||a[x+bx[k]][y+by[k]]==0|| (x+bx[k]==i&&y+by[k]==j) ) 72 continue; 73 //printf("sdasdasd\n"); 74 if(d[x+bx[k]][y+by[k]]>d[x][y]+1) 75 { 76 d[x+bx[k]][y+by[k]]=d[x][y]+1; 77 if(!flag[x+bx[k]][y+by[k]]) 78 { 79 q.push((Queue){x+bx[k],y+by[k]}); 80 flag[x+bx[k]][y+by[k]]=1; 81 } 82 } 83 } 84 } 85 86 //g[i][j][bai][tt]=d[tx][ty]+1; 87 g[i][j][bai][tt]=d[tx][ty]; 88 89 //out11(); 90 91 //printf("i=%d j=%d k=%d l=%d g[][][][]=%d\n",i,j,bai,tt,g[i][j][bai][tt]); 92 } 93 } 94 } 95 }// yes 96 97 int bfs1() 98 { 99 Queue now; 100 int x,y; 101 mem(d,60); 102 while(!q.empty())q.pop(); 103 mem(flag,0); 104 d[whx][why]=0;flag[whx][why]=1; 105 q.push((Queue){whx,why}); 106 while(!q.empty()) 107 { 108 now=q.front();q.pop(); 109 x=now.x;y=now.y;flag[x][y]=0; 110 for(int k=1;k<=4;++k) 111 { 112 if(x+bx[k]<1||x+bx[k]>n||y+by[k]<1||y+by[k]>m||a[x+bx[k]][y+by[k]]==0|| (x+bx[k]==sx&&y+by[k]==sy) ) 113 continue; 114 if(d[x+bx[k]][y+by[k]]>d[x][y]+1) 115 { 116 d[x+bx[k]][y+by[k]]=d[x][y]+1; 117 if(!flag[x+bx[k]][y+by[k]]) 118 { 119 q.push((Queue){x+bx[k],y+by[k]}); 120 flag[x+bx[k]][y+by[k]]=1; 121 } 122 } 123 } 124 } 125 126 for(int i=1;i<=4;++i) 127 if(d[sx+bx[i]][sy+by[i]]<qqq) 128 return 1; 129 return 0; 130 } 131 132 struct son 133 { 134 int x,y,k; 135 }; 136 queue<son> dui; 137 138 int bfs2() 139 { 140 son now; 141 int x,y,nowk; 142 mem(f,60);mem(vis,0); 143 for(int i=1;i<=4;++i) 144 { 145 if(sx+bx[i]<1||sx+bx[i]>n||sy+by[i]<1||sy+by[i]>m||a[sx+bx[i]][sy+by[i]]==0||d[sx+bx[i]][sy+by[i]]==qqq) 146 continue; 147 f[sx][sy][i]=d[sx+bx[i]][sy+by[i]]; 148 vis[sx][sy][i]=1; 149 //printf("ssdad=%d\n",d[sx+bx[i]][sy+by[i]]); 150 dui.push((son){sx,sy,i}); 151 } 152 153 //out11(); 154 155 while(!dui.empty()) 156 { 157 now=dui.front();dui.pop(); 158 x=now.x;y=now.y;nowk=now.k; 159 vis[x][y][nowk]=0; 160 161 for(int i=1;i<=4;++i) 162 { 163 if(x+bx[i]<1|| (x+bx[i]>n) || (y+by[i]<1) || (y+by[i]>m) || (a[x+bx[i]][y+by[i]]==0) ) 164 continue; 165 //printf("hhahahahahha\n"); 166 int temp1=f[x+bx[i]][y+by[i]][ha[i]]; 167 int temp2=f[x][y][nowk]+1+g[x][y][nowk][i]; 168 //printf("%d %d\n",temp1,temp2); 169 if(temp1>temp2) 170 { 171 172 f[x+bx[i]][y+by[i]][ha[i]]=f[x][y][nowk]+1+g[x][y][nowk][i]; 173 if(!vis[x+bx[i]][y+by[i]][ha[i]])//////???????? 174 { 175 dui.push((son){x+bx[i],y+by[i],ha[i]}); 176 vis[x+bx[i]][y+by[i]][ha[i]]=1; 177 } 178 } 179 } 180 } 181 182 //out11(); 183 184 int ans=INF; 185 for(int i=1;i<=4;++i) 186 ans=minn(ans,f[tx][ty][i]); 187 return ans; 188 } 189 190 void out11() 191 { 192 printf("\n"); 193 for(int k=1;k<=4;++k) 194 { 195 for(int i=1;i<=n;++i) 196 { 197 for(int j=1;j<=m;++j) 198 printf("%d ",f[i][j][k]); 199 printf("\n"); 200 } 201 printf("\n"); 202 } 203 204 /*for(int i=1;i<=n;++i) 205 { 206 for(int j=1;j<=m;++j) 207 printf("%d ",d[i][j]); 208 printf("\n"); 209 }*/ 210 /*for(int i=1;i<=n;++i) 211 for(int j=1;j<=m;++j) 212 for(int k=1;k<=4;++k) 213 for(int l=1;l<=4;++l) 214 if(g[i][j][k][l]!=qqq) 215 printf("i=%d j=%d k=%d l=%d g[][][][]=%d\n",i,j,k,l,g[i][j][k][l]);*/ 216 printf("\n"); 217 } 218 219 int main(){ 220 221 //freopen("1.txt","r",stdin); 222 223 scanf("%d%d%d",&n,&m,&Q); 224 for(int i=1;i<=n;++i) 225 for(int j=1;j<=m;++j) 226 scanf("%d",&a[i][j]); 227 chu(); 228 ha[1]=2;ha[2]=1;ha[3]=4;ha[4]=3; 229 230 //out11(); 231 232 while(Q--) 233 { 234 scanf("%d%d%d%d%d%d",&whx,&why,&sx,&sy,&tx,&ty); 235 if(sx==tx&&sy==ty) 236 { 237 printf("0\n"); 238 continue; 239 } 240 if(bfs1()==0) 241 { 242 printf("-1\n"); 243 continue; 244 } 245 int temp=bfs2(); 246 if(temp>=qqq) 247 { 248 printf("-1\n"); 249 continue; 250 } 251 printf("%d\n",temp); 252 } 253 254 //while(1); 255 return 0; 256 }
以上是关于noip2013 华容道的主要内容,如果未能解决你的问题,请参考以下文章