码迷,mamicode.com
首页 > 其他好文 > 详细

USACO Section 3.3 Camlot

时间:2015-02-15 19:16:29      阅读:155      评论:0      收藏:0      [点我收藏+]

标签:

技术分享

  BFS.先算出棋盘上每个点到各个点knight需要的步数;然后枚举所有点,其中再枚举king是自己到的还是knight带它去的(假如是knight带它的,枚举king周围的2格(网上都这么说,似乎是个结论?还是usaco数据太弱了?不过看跑出来的时间,全部枚举或许也可以))。一开始觉得挺麻烦的,不过只要思路清晰写起来应该也没多大问题。大概就是这样了.

技术分享
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<queue>
#include<cmath>

#define rep(i,l,r) for(int i=l;i<=r;i++)
#define dow(i,l,r) for(int i=l;i>=r;i--)
#define clr(x,c) memset(x,c,sizeof x)

using namespace std;

const int inf=0x3f3f3f3f,maxr=30+5,maxc=26+5;
const int dir[8][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
int d[maxr][maxc][maxr][maxc];
int r,c,num=0;

struct coor { int x,y; };

queue<coor> q;
coor king,knight[maxr*maxc];

void init() {
    cin>>r>>c;
    char p;
    int t;
    cin>>p>>t;
    king={t,p-A+1};
    while(cin>>p>>t) knight[++num]={t,p-A+1};
    
    clr(d,inf);
    rep(i,1,r) rep(j,1,c) {
        d[i][j][i][j]=0;
        q.push((coor){i,j});
        while(!q.empty()) {
            coor e=q.front(); q.pop();
            rep(k,0,7) {
                int x=e.x+dir[k][0];
                int y=e.y+dir[k][1];
                if(x<=0 || x>r || y<=0 || y>c) continue;
                if(d[i][j][x][y]==inf) {
                    d[i][j][x][y]=d[i][j][e.x][e.y]+1;
                    q.push((coor){x,y});
                }
            }
        }
    }
}

int s() {
    int ans=inf;
    int i=5,j=2;
    rep(i,1,r) rep(j,1,c) {
        int w=0,t=inf;
        rep(k,1,num) {
            coor e=knight[k];
            w+=d[i][j][e.x][e.y];
        }
        
        rep(a,max(king.x-2,1),min(king.x+2,r))
            rep(b,max(king.y-2,1),min(king.y+2,c)) 
                rep(k,1,num) {
                    coor e=knight[k];
                    int x=abs(king.x-a);
                    int y=abs(king.y-b);
                    t=min(t,d[i][j][a][b]+d[a][b][e.x][e.y]+x+y-min(x,y)-d[i][j][e.x][e.y]);
                }
        
        int x=abs(king.x-i);
        int y=abs(king.y-j);
        int h=min(x+y-min(x,y),t)+w;
        ans= h>=0 && h<ans ? h:ans;
    }
    return ans;
}

int main() {
    freopen("camelot.in","r",stdin);
    freopen("camelot.out","w",stdout);
    
    init();
    cout<<s()<<endl;
    
    fclose(stdin);
    fclose(stdout);
    return 0;
}
View Code

 

USACO Section 3.3 Camlot

标签:

原文地址:http://www.cnblogs.com/JSZX11556/p/4293332.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!