Description
Solution
这题时限开的挺大的。。。
由于时限较大,我们可以预处理出每个坐标走日字步到另一坐标的最短距离, O(r3c3) 的Floyd可以解决(可以考虑用spfa,但这里的点入队时间较长)。
然后我们枚举两个汇合点,我们贪心的想,一个骑士走到第一个坐标距离如果比走到第二个的小的多,那么我们肯定不走到第二个坐标,反之就不走到第一个坐标。
于是,设第
i
个骑士到坐标A的距离为
Code
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define fo(i,j,k) for(int i=j;i<=k;i++)
#define fd(i,j,k) for(int i=j;i>=k;i--)
#define N 21
#define ll long long
using namespace std;
int f[N][N][N][N];
struct node{
int x,y,z;
}a[N*N];
bool cmp(node x,node y)
{
return x.z<y.z;
}
int fx[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{2,-1},{-2,1},{-2,-1}};
int main()
{
freopen("4622.in","r",stdin);
freopen("4622.out","w",stdout);
int n,r,c;
cin>>n>>r>>c;
fo(i,1,n)
scanf("%d %d",&a[i].x,&a[i].y);
memset(f,60,sizeof(f));
fo(i,1,r)
fo(j,1,c)
fo(k,0,7)
f[i][j][i+fx[k][0]][j+fx[k][1]]=1;
fo(i,1,r)
fo(j,1,c)
f[i][j][i][j]=0;
fo(kx,1,r)
fo(ky,1,c)
fo(ix,1,r)
fo(iy,1,c)
fo(jx,1,r)
fo(jy,1,c)
if(f[ix][iy][jx][jy]>f[ix][iy][kx][ky]+f[kx][ky][jx][jy])
f[ix][iy][jx][jy]=f[ix][iy][kx][ky]+f[kx][ky][jx][jy];
int ans=2147483647;
fo(i1,1,r)
fo(j1,1,c)
fo(i2,1,r)
fo(j2,1,c)
{
if(i1==i2 && j1==j2) continue;
int tmp=0;
fo(k,1,n)
a[k].z=f[a[k].x][a[k].y][i1][j1]-f[a[k].x][a[k].y][i2][j2];
sort(a+1,a+n+1,cmp);
fo(k,1,n/2) tmp+=f[a[k].x][a[k].y][i1][j1];
fo(k,n/2+1,n) tmp+=f[a[k].x][a[k].y][i2][j2];
if(tmp<ans) ans=tmp;
}
cout<<ans;
}