2012-A3-0027
从 Trac 迁移的文章
这是从旧校内 Wiki 迁移的文章,可能存在一些样式问题,您可以向 memset0 反馈。
原文章内容如下:
{{{
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<cstring>
#include<cassert>
using namespace std;
const char info[]="We need God's help!";
#define InCase(x) if(__builtin_expect((x),0))
const int dx[]= {0,1,0,-1},dy[]={1,0,-1,0};
int f[50][50][32],mx[8],my[8],g[50][50],n,m,o,l,xs,ys,xd,yd;
vector<int> old,xin;
inline int zt(int x,int y,int li,int fz){
return ((x<<8|y)<<4|li)<<5|fz;
}
inline int mnst(int x,int y){
for(int i=0;i<o;++i)
if(x==mx[i]&&y==my[i])
return i;
return -1;
}
inline int calc(int t,int l){
return (t<<8)-l;
}
int solve(){
int tmp,tx,ty,tl,tz,x,y,li,fz;
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
memset(f[i][j],0x3f,128);
//f[xs][ys][0] = calc(0,0);
old.clear();
xin.clear();
if(xs == xd && ys == yd)return 0;
xin.push_back(zt(xs,ys,l,0));
for(int turns=1;xin.size();++turns){
xin.swap(old);
for(;old.size();){
x = (*old.rbegin())>>17&63;
y = (*old.rbegin())>>9&63;
li= (*old.rbegin())>>5&15;
fz= (*old.rbegin())&31;
InCase( ~(tmp = mnst(x,y)))
fz|= 1<< tmp;
old.pop_back();
//printf("%d: X%d Y%d L%d Z%d\n",turns,x,y,li,fz);
InCase(x == xd && y==yd)
return turns;
for(int i=0;i<4;++i){
tx = x + dx[i];
ty = y + dy[i];
InCase(tx<0 || ty<0 || tx>=n || ty>=m || g[tx][ty]==-1)
continue;
tl = li - 1;
if(g[tx][ty] && !(fz&(1<<g[tx][ty]-1)))
tl =0;
InCase(tx == xd && ty == yd)return turns;
if(tl){
if(f[tx][ty][fz]>calc(turns,tl)){
old.push_back(zt(tx,ty,tl,fz));
f[tx][ty][fz]=calc(turns,tl);
}
}else{
if(f[tx][ty][fz]> calc(turns + 1,l)){
xin.push_back(zt(tx,ty,l,fz));
f[tx][ty][fz]= calc(turns + 1,l);
}
}
}
}
}
return ~0;
}
int main(){
for(int ans,cnt =1;scanf("%d%d%d",&n,&m,&l)==3;++cnt){
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
scanf("%d",&g[i][j]);
scanf("%d",&o);
for(int i =0;i<o;++i){
scanf("%d%d",mx+i,my+i);
--mx[i];--my[i];
}
scanf("%d%d%d%d",&xs,&ys,&xd,&yd);
--xs;--ys;--xd;--yd;
~(ans = solve())? printf("%d\n",ans):puts(info);
/*ans = solve();
InCase(cnt == 13){
printf("%d %d %d\n",n,m,l);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
printf("%d%c",g[i][j],(j+1==m)?'\n':' ');
printf("%d\n",o);
for(int i =0;i<o;++i)
printf("%d %d\n",mx[i]+1,1+my[i]);
printf("%d %d %d %d\n",xs+1,ys+1,xd+1,yd+1);
return 0;
}*/
}
return 0;
}
}}}
#include<cstdio>
#include<vector>
#include<queue>
#include<stack>
#include<algorithm>
#include<cstring>
#include<cassert>
using namespace std;
const char info[]="We need God's help!";
#define InCase(x) if(__builtin_expect((x),0))
const int dx[]= {0,1,0,-1},dy[]={1,0,-1,0};
int f[50][50][32],mx[8],my[8],g[50][50],n,m,o,l,xs,ys,xd,yd;
vector<int> old,xin;
inline int zt(int x,int y,int li,int fz){
return ((x<<8|y)<<4|li)<<5|fz;
}
inline int mnst(int x,int y){
for(int i=0;i<o;++i)
if(x==mx[i]&&y==my[i])
return i;
return -1;
}
inline int calc(int t,int l){
return (t<<8)-l;
}
int solve(){
int tmp,tx,ty,tl,tz,x,y,li,fz;
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
memset(f[i][j],0x3f,128);
//f[xs][ys][0] = calc(0,0);
old.clear();
xin.clear();
if(xs == xd && ys == yd)return 0;
xin.push_back(zt(xs,ys,l,0));
for(int turns=1;xin.size();++turns){
xin.swap(old);
for(;old.size();){
x = (*old.rbegin())>>17&63;
y = (*old.rbegin())>>9&63;
li= (*old.rbegin())>>5&15;
fz= (*old.rbegin())&31;
InCase( ~(tmp = mnst(x,y)))
fz|= 1<< tmp;
old.pop_back();
//printf("%d: X%d Y%d L%d Z%d\n",turns,x,y,li,fz);
InCase(x == xd && y==yd)
return turns;
for(int i=0;i<4;++i){
tx = x + dx[i];
ty = y + dy[i];
InCase(tx<0 || ty<0 || tx>=n || ty>=m || g[tx][ty]==-1)
continue;
tl = li - 1;
if(g[tx][ty] && !(fz&(1<<g[tx][ty]-1)))
tl =0;
InCase(tx == xd && ty == yd)return turns;
if(tl){
if(f[tx][ty][fz]>calc(turns,tl)){
old.push_back(zt(tx,ty,tl,fz));
f[tx][ty][fz]=calc(turns,tl);
}
}else{
if(f[tx][ty][fz]> calc(turns + 1,l)){
xin.push_back(zt(tx,ty,l,fz));
f[tx][ty][fz]= calc(turns + 1,l);
}
}
}
}
}
return ~0;
}
int main(){
for(int ans,cnt =1;scanf("%d%d%d",&n,&m,&l)==3;++cnt){
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
scanf("%d",&g[i][j]);
scanf("%d",&o);
for(int i =0;i<o;++i){
scanf("%d%d",mx+i,my+i);
--mx[i];--my[i];
}
scanf("%d%d%d%d",&xs,&ys,&xd,&yd);
--xs;--ys;--xd;--yd;
~(ans = solve())? printf("%d\n",ans):puts(info);
/*ans = solve();
InCase(cnt == 13){
printf("%d %d %d\n",n,m,l);
for(int i=0;i<n;++i)
for(int j=0;j<m;++j)
printf("%d%c",g[i][j],(j+1==m)?'\n':' ');
printf("%d\n",o);
for(int i =0;i<o;++i)
printf("%d %d\n",mx[i]+1,1+my[i]);
printf("%d %d %d %d\n",xs+1,ys+1,xd+1,yd+1);
return 0;
}*/
}
return 0;
}