POJ_1178_Camelot(floyd+枚举)

#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
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值