POJ_1178_Camelot

#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;
#define BOARDSIZE 8
#define POWBOARDSIZE 64
#define SIZE 10
#define INF 0x3f3f3f3f
#define MAX 70
struct Point{
int x;
int y;
};

Point King,Knight[MAX];
int dist[SIZE][SIZE][SIZE][SIZE];
char caArr[256];
int nCountKnight;

void floyd(){
for( int i = 0; i < BOARDSIZE; ++i )
for( int j = 0; j < BOARDSIZE; ++j )
for( int k = 0; k < BOARDSIZE; ++k )
for( int h = 0; h < BOARDSIZE; ++h ){
if( ( abs( i - k ) == 1 && abs( j - h ) == 2 ) ||
( abs( i - k ) == 2 && abs( j - h ) == 1 ) ) dist[i][j][k][h] = 1;
else dist[i][j][k][h] = INF;
}
for( int i = 0; i < BOARDSIZE; ++i )
for( int j = 0; j < BOARDSIZE; ++j ) dist[i][j][i][j] = 0;

for( int k = 0; k < POWBOARDSIZE; ++k )
for( int j = 0; j < POWBOARDSIZE; ++j )
for( int i = 0; i < POWBOARDSIZE; ++i ){
int tx = k / BOARDSIZE;
int ty = k % BOARDSIZE;
int x1 = j / BOARDSIZE;
int y1 = j % BOARDSIZE;
int x2 = i / BOARDSIZE;
int y2 = i % BOARDSIZE;
dist[x1][y1][x2][y2] = min( dist[x1][y1][x2][y2], dist[x1][y1][tx][ty] + dist[tx][ty][x2][y2] );
}
}

void treatString(){
King.x = caArr[0] - 'A';
King.y = caArr[1] - '1';
int count = 0;
for( int i = 2; i < strlen(caArr); i += 2 ){
Knight[count].x = caArr[i] - 'A';
Knight[count].y = caArr[i+1] - '1';
count++;
}
nCountKnight = strlen(caArr)/2 - 1;
}

void work(){
if( nCountKnight == 0 ) printf("0\n");
int ans = INF;
for( int i = 0; i < POWBOARDSIZE; ++i ){
int x = i / BOARDSIZE;
int y = i % BOARDSIZE;
int sum = 0;
for( int j = 0; j < nCountKnight; ++j ) sum += dist[x][y][Knight[j].x][Knight[j].y];
for( int k = 0; k < POWBOARDSIZE; ++k ){
Point cross;
cross.x = k / BOARDSIZE;
cross.y = k % BOARDSIZE;
int temp1 = max( abs(cross.x - King.x ), abs( cross.y - King.y ) );
int temp2 = INF;
for( int h = 0; h < nCountKnight; ++h ){
temp2 = min( temp2, dist[x][y][cross.x][cross.y] + dist[cross.x][cross.y][Knight[h].x][Knight[h].y] - dist[x][y][Knight[h].x][Knight[h].y] );
ans = min( ans, temp1 + temp2 + sum );
}
}
}
cout<<ans<<endl;
}

int main(){
scanf("%s",caArr);
floyd();
treatString();
work();
return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值