题目传送门:http://www.nocow.cn/index.php/Translate:USACO/camelot
这道题让我心痛,一开始写写不出,后来拖了很久,决定去看题解,没想到又看不懂官方题解,唉!后来看了下面的题解做了出来。题解的话,大概就是先预处理每个格子到另外格子的位置,再枚举在王的坐标+-2位置接王,枚举所有棋子的集中点加起来计算就好了。我的代码为了方便略粗鲁。
题解传送门:http://www.nocow.cn/index.php/USACO/camelot
/* ID:abc31261 LANG:C++ TASK:camelot */ #include<cstdio> #include<cstring> #include<queue> #include<iostream> using namespace std; const int maxn=33,maxm=800; int n,m,ans=100000000,flag[maxn][maxn],f1[2][maxn][maxn][maxn][maxn],f[maxn][maxn],num=-1,numx[maxm],numy[maxm],knx[]={0,-2,-2,-1,-1,1,1,2,2},kny[]={0,-1,1,-2,2,-2,2,-1,1}, ky[]={0,-1,0,1,-1,1,-1,0,1},kx[]={0,-1,-1,-1,0,0,1,1,1}; void read() { char in[5]; scanf("%d%d",&n,&m); while (scanf("%s%d",in,&numx[++num])==2)numy[num]=in[0]-'A'+1; num--; } bool check(int x,int y) { if (x<=n && x>0 && y<=m && y>0)return true; return false; } void bfs(int a,int b,int c) { queue<int> qx,qy; qx.push(a),qy.push(b); memset(flag,true,sizeof(flag)); flag[a][b]=false; f1[c][a][b][a][b]=0; while (!qx.empty()) { int x=qx.front(),y=qy.front();qx.pop(),qy.pop(); for (int i=1;i<=8;i++) { int x1=x+knx[i],y1=y+kny[i]; if (c==1)x1=x+kx[i],y1=y+ky[i]; if (check(x1,y1) && flag[x1][y1]) { qx.push(x1),qy.push(y1); flag[x1][y1]=false; f1[c][a][b][x1][y1]=f1[c][a][b][x][y]+1; } } } } void solve() { int q,i,j,l,k; for (i=1;i<=n;i++) for (j=1;j<=m;j++) { f[i][j]+=f1[1][numx[0]][numy[0]][i][j]; ans=min(ans,f[i][j]); } for (q=1;q<=num;q++) for (i=1;i<=n;i++) for (j=1;j<=m;j++) for (l=numx[0]-2;l<=numx[0]+2;l++) for (k=numy[0]-2;k<=numy[0]+2;k++) if (l>0 && l<=n && k>0 && k<=m) ans=min(f1[1][numx[0]][numy[0]][l][k]+f1[0][numx[q]][numy[q]][l][k]+f1[0][l][k][i][j]+f[i][j]-f1[0][numx[q]][numy[q]][i][j]-f1[1][numx[0]][numy[0]][i][j],ans); } int main() { int i,j,l; freopen("camelot.in","r",stdin); freopen("camelot.out","w",stdout); read(); memset(f,0,sizeof(f)); memset(f1,0x2f,sizeof(f1)); bfs(numx[0],numy[0],1); for (i=1;i<=n;i++) for (j=1;j<=m;j++)bfs(i,j,0); for (i=1;i<=num;i++) for (j=1;j<=n;j++) for (l=1;l<=m;l++) f[j][l]+=f1[0][numx[i]][numy[i]][j][l]; solve(); cout<<ans<<endl; return 0; }