POJ 1178 Camelot 最短路 Floyd +枚举

题目大意:在一个8*8的棋盘里有一个国王和一些骑士,我们须要把他们送到同一顶点上去,骑士和国王的行动方式如图所看到的。国王能够选择一名骑士作为坐骑。上马后相当和该骑士
          一起行动(相当于一个骑士),同一位置能够同一时候有多个骑士和国王。问最少走的步数

解题思路:把8*8棋盘变成0~63的数,Floyd求出随意两点之间的最短路径。8*8枚举就可以。枚举终点,骑士上马点,国王上哪个骑士,终于负责度O(64^4)。

#include <string.h>
#include <algorithm>
#include <iostream>
#include <stdio.h>
using namespace std;

char s[105];
int cx[8][2]= {{-2,-1},{-2,1},{-1,-2},{-1,2},{1,-2},{1,2},{2,-1},{2,1}};
int dx[8][2]= {{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}};
int a[65][65],b[65][65],rking[65],king;

bool judge(int i,int j)
{
    if(i>=0&&i<8&&j>=0&&j<8)
        return true;
    return false;
}

void init()
{
    for(int i=0; i<64; i++)
    {
        for(int j=0; j<64; j++)
        {
            if(i==j)
                a[i][j]=b[i][j]=0;
            else
                a[i][j]=b[i][j]=999;
        }
    }
    for(int i=0; i<8; i++)
    {
        for(int j=0; j<8; j++)
        {
            for(int k=0; k<8; k++)
            {
                int x=i+cx[k][0];
                int y=j+cx[k][1];
                int xx=i+dx[k][0];
                int yy=j+dx[k][1];
                if(judge(x,y))
                {
                    a[i+j*8][x+y*8]=1;
                }
                if(judge(xx,yy))
                {
                     b[i+j*8][xx+yy*8]=1;
                }
            }
        }
    }
    for(int k=0; k<64; k++)
    {
        for(int i=0; i<64; i++)
        {
            for(int j=0; j<64; j++)
            {
                a[i][j]=min(a[i][j],a[i][k]+a[k][j]);
                b[i][j]=min(b[i][j],b[i][k]+b[k][j]);
            }
        }
    }
}
int main()
{
    init();
    while(~scanf("%s",s))
    {
        int n=strlen(s);
        king=s[0]-'A'+(s[1]-'1')*8;
        int cnt=0;
        for(int i=2; i<n; i+=2)
        {
            int x=s[i+1]-'1';
            int y=s[i]-'A';
            rking[cnt++]=x*8+y;
        }
        int ans=9999999;
        for(int i=0;i<64;i++)///终点
        {
            for(int j=0;j<64;j++)///国王上马点
            {
                for(int k=0;k<cnt;k++)///国王所上的骑士
                {
                    int sum=0;
                    for(int l=0;l<cnt;l++)
                    {
                        if(l==k)continue;
                        sum+=a[rking[l]][i];
                    }
                    sum+=b[king][j]+a[rking[k]][j]+a[j][i];
                    ans=min(ans,sum);
                }
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章