[USACO3.3.3]camelot

  题目传送门: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;
}
原文地址:https://www.cnblogs.com/Sun-Sea/p/5289831.html