120718 测试 NOIP 模拟题 T2迷宫
题目
分析
搜索要炸
只好DP
方程如下
经典建模
code
#include<bits/stdc++.h>
using namespace std;
#define loop(i,start,end) for(int i=start;i<=end;i++)
#define anti_loop(i,start,end) for(int i=start;i>=end;i--)
#define clean(arry,num); memset(arry,num,sizeof(arry));
#define min(a,b) ((a<b)?a:b)
#define ll long long
#define lowbit(a) (a&(-a))
int n;
int s_x,s_y,m_x,m_y;
const int maxn=30;
const int maxk=maxn*maxn;
int g[maxn][maxn];
int f[maxn][maxn][maxk];
int dx[4]={0,0,1,-1};
int dy[4]={-1,1,0,0};
inline int read()
{
int neg=1;int ans=0;char r=getchar();
while(r>'9'||r<'0'){if(r=='-')neg=-1;r=getchar();}
while(r>='0'&&r<='9'){ans=ans*10+r-'0';r=getchar();}
return ans*neg;
}
void DP()
{
clean(f,0);
f[s_x][s_y][0]=1;
loop(k,1,n*n)
{
loop(x,1,n)
{
loop(y,1,n)
{
if(g[x][y]==-1)continue;
loop(z,0,3)
{
int nx=x+dx[z];
int ny=y+dy[z];
if(g[nx][ny]==-1)continue;
f[x][y][k]+=f[nx][ny][k-1];
}
}
}
}
loop(k,1,n*n)//步数最大n x n,从小到大枚举,第一个不为零的即是最短路
{
if(f[m_x][m_y][k])
{
printf("%d\n%d",k,f[m_x][m_y][k]);
return;
}
}
}
int main()
{
//freopen("datain.txt","r",stdin);
n=read();
char s[maxn];
clean(g,-1);
loop(i,1,n)
{
scanf("%s",s);
loop(j,0,n-1)
{
if(s[j]=='E'){s_x=i;s_y=j+1;g[i][j+1]=0;}
else if(s[j]=='X'){g[i][j+1]=-1;}
else if(s[j]=='.'){g[i][j+1]=0;}
else if(s[j]=='S'){m_x=i;m_y=j+1;g[m_x][m_y]=0;};
}
}
DP();
return 0;
}