usaco3.3.4亚瑟王的宫殿
2014-08-03 15:53
411 查看
一个万无一失的方法
对于骑士带王去会合的情况,枚举王的原位置和八个方向,也就是说王和骑士的汇合点相对于王的原位置为上下左右或者斜45度方向。比如在8*8的棋盘上,王的位置用k表示,需要枚举的带王的点用1表示,其余点用0表示则有下图:
0 0 1 0 0 1 0 0 1 0 1 0 1 0 0 0 0 1 1 1 0 0 0 0 1 1 k 1 1 1 1 1 0 1 1 1 0 0 0 0 1 0 1 0 1 0 0 0 0 0 1 0 0 1 0 0 0 0 1 0 0 0 1 0
对于其他带王点的情况,总可以等效为以上情况之一,这样枚举不会超时。
需要注意的是,输入时的R,C分别代表列数和行数。
主要用bfs,搜出对于每一个knight到达每一个格子所需的步数。(调试了一个下午,结果是字母打错了,好想骂人啊)
具体思路看代码吧。
#include<cstdio>
#include<iostream>
#include <queue>
#include <cmath>
#include <algorithm>
using namespace std;
struct aaaa{int x,y,d;};
int moveking[8][2]={{-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1}};
int moveknight[8][2]={{-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1}};
int king[2],knight[1041][2],kingdist[27][41];
int disttoking[200][27][41];
int dist[1041][27][41],zonghe[27][41],R,C,numknight=1,num=0;
void bfs(int s[2],int move[8][2],int dist1[27][41]);
int main()
{
//freopen("camelot.in","r",stdin);
//freopen("camelot.out","w",stdout);
cin>>C>>R;
char a;
cin>>a>>king[1];
king[0]=a-64;
while(cin>>a>>knight[numknight][1])
{
knight[numknight][0]=a-64;
numknight++;
}
numknight--;
bfs(king,moveking,kingdist);
for(int i=0;i<8;i++)
{
int s[2];
s[0]=king[0]+moveking[i][0];
s[1]=king[1]+moveking[i][1];
while(s[0]>0&&s[0]<=R&&s[1]>0&&s[1]<=C)
{
bfs(s,moveknight,disttoking[num++]);
s[0]=s[0]+moveking[i][0];
s[1]=s[1]+moveking[i][1];
}
}
bfs(king,moveknight,disttoking[num]);
for(int i=1;i<=numknight;i++)
{
bfs(knight[i],moveknight,dist[i]);
}
int min1=99999999,lala;
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++)
for(int k=1;k<=numknight;k++)
zonghe[i][j]+=dist[k][i][j];
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++)
{
lala=zonghe[i][j]+kingdist[i][j];
if(lala<min1)min1=lala;
for(int l=1;l<=numknight;l++)
{
lala=zonghe[i][j]-dist[l][i][j];
lala+=dist[l][king[0]][king[1]];
lala+=disttoking[num][i][j];
if(lala<min1)min1=lala;
int bu=0;
for(int i1=0;i1<8;i1++)
{
int s[2],shu=1;
s[0]=king[0]+moveking[i1][0];
s[1]=king[1]+moveking[i1][1];
while(s[0]>0&&s[0]<=R&&s[1]>0&&s[1]<=C)
{
lala=disttoking[bu][i][j];
lala+=dist[l][s[0]][s[1]];
lala+=shu;
lala+=(zonghe[i][j]-dist[l][i][j]);
shu++;
bu++;
if(lala<min1)min1=lala;
s[0]=s[0]+moveking[i1][0];
s[1]=s[1]+moveking[i1][1];
}
}
}
}
cout<<min1<<endl;
return 0;
}
void bfs(int s[2],int move[8][2],int dist1[27][41])
{
bool done[27][41];
queue<aaaa>q;
while(!q.empty())q.pop();
for(int i=1;i<=R;i++)for(int j=1;j<=C;j++){done[i][j]=false;dist1[i][j]=99999999;}
dist1[s[0]][s[1]]=0;
q.push((aaaa){s[0],s[1],0});
done[s[0]][s[1]]=true;
while(!q.empty()){
aaaa key=q.front();
q.pop();
for(int i=0;i<8;i++)
{
aaaa kk;
kk.x=key.x+move[i][0];
kk.y=key.y+move[i][1];
if(kk.x>0&&kk.x<=R&&kk.y>0&&kk.y<=C&&!done[kk.x][kk.y]){
done[kk.x][kk.y]=true;
dist1[kk.x][kk.y]=key.d+1;
kk.d=key.d+1;
q.push(kk);
}
}
}
}
可能这个更清楚:
#include<stdio.h> #include<stdlib.h> #define LENQUE 781 #define INFI 500 FILE *fin,*fout; int R,C; int dist[781][31][27]; int total[31][27]; int distking[31][27]; int distride[120][31][27]; int numride; int king[2]; int numknight; int knight[781][2]; int moveknight[8][2]={ {-2,1},{-1,2},{1,2},{2,1},{2,-1},{1,-2},{-1,-2},{-2,-1} }; int moveking[8][2]={ {-1,0},{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1} }; int queue[LENQUE][3]; bool done[31][27]; void bfs(int s[2],int move[8][2],int distmemo[31][27]){ int i,j; for(i=0;i<R;i++)for(j=0;j<C;j++)done[i][j]=false; for(i=0;i<R;i++)for(j=0;j<C;j++)distmemo[i][j]=INFI; distmemo[s[0]][s[1]]=0; done[s[0]][s[1]]=true; int head=0,tail=1; queue[0][0]=s[0]; queue[0][1]=s[1]; queue[0][2]=0; while(head!=tail){ for(i=0;i<8;i++){ int temp[2]; temp[0]=queue[head][0]+move[i][0]; temp[1]=queue[head][1]+move[i][1]; if(temp[0]>=0&&temp[0]<R&&temp[1]>=0&&temp[1]<=C){ if(!done[temp[0]][temp[1]]){ queue[tail][0]=temp[0]; queue[tail][1]=temp[1]; queue[tail][2]=queue[head][2]+1; done[temp[0]][temp[1]]=true; distmemo[temp[0]][temp[1]]=queue[tail][2]; tail=(tail+1)%LENQUE; } } } head=(head+1)%LENQUE; } } int main(){ fin=fopen("camelot.in","r"); fout=fopen("camelot.out","w"); fscanf(fin,"%d %d\n",&R,&C); char col; int row; fscanf(fin,"%c %d",&col,&row); king[0]=row-1; king[1]=col-'A'; while(fscanf(fin,"%c",&col)!=EOF){ if(col==' '||col=='\n')continue; fscanf(fin,"%d",&row); knight[numknight][0]=row-1; knight[numknight][1]=col-'A'; numknight++; } int i; bfs(king,moveking,distking); for(i=0;i<8;i++){ int temp[2]; temp[0]=king[0]+moveking[i][0]; temp[1]=king[1]+moveking[i][1]; while(temp[0]>=0&&temp[0]<R&&temp[1]>=0&&temp[1]<C){ bfs(temp,moveknight,distride[numride++]); temp[0]=temp[0]+moveking[i][0]; temp[1]=temp[1]+moveking[i][1]; } } bfs(king,moveknight,distride[numride++]); for(i=0;i<numknight;i++){ bfs(knight[i],moveknight,dist[i]); } int min=0x7fffffff; int gr,gc,ride,d,move; for(gr=0;gr<R;gr++)for(gc=0;gc<C;gc++){ for(i=0;i<numknight;i++){ total[gr][gc]+=dist[i][gr][gc]; } } for(gr=0;gr<R;gr++)for(gc=0;gc<C;gc++){ d=distking[gr][gc]+total[gr][gc]; if(d<min)min=d; for(ride=0;ride<numknight;ride++){ d=distride[numride-1][gr][gc]; d+=dist[ride][king[0]][king[1]]; d+=total[gr][gc]-dist[ride][gr][gc]; if(d<min)min=d; int po=0,countking=0; for(i=0;i<8;i++){ int temp[2]; temp[0]=king[0]+moveking[i][0]; temp[1]=king[1]+moveking[i][1]; countking=1; while(temp[0]>=0&&temp[0]<R&&temp[1]>=0&&temp[1]<C){ d=distride[po][gr][gc]; d+=countking; d+=dist[ride][temp[0]][temp[1]]; d+=total[gr][gc]-dist[ride][gr][gc]; if(d<min)min=d; po++; countking++; temp[0]=temp[0]+moveking[i][0]; temp[1]=temp[1]+moveking[i][1]; } } } } fprintf(fout,"%d\n",min); return 0; }
相关文章推荐
- 【USACO3.3.3】亚瑟王的宫殿
- 【USACO题库】3.3.3 Camelot亚瑟王的宫殿
- [USACO3.3]亚瑟王的宫殿 Camelot
- USACO Training 3.3.3 Camelot 亚瑟王的宫殿 题解与分析
- USACO Training3.3亚瑟王的宫殿【搜索】By cellur925
- 洛谷P1930 亚瑟王的宫殿 Camelot
- [USACO3.3.4]Home on the Range
- 洛谷P1930 亚瑟王的宫殿 Camelot
- USACO/range 3.3.4
- USACO3.3.4 Home on the Range (range)
- USACO 3.3.4
- USACO3.3.4--Home on the Range
- USACO3.3.4 Home on the Range (range)
- 【USACO3.3.4】家的范围
- 洛谷 P1930 亚瑟王的宫殿 Camelot
- bzoj1615 [Usaco2008 Mar]The Loathesome Hay Baler麻烦的干草打包机
- 【BZOJ 1594】 [Usaco2008 Jan]猜数游戏 (二分+并查集)
- BZOJ 1607: [Usaco2008 Dec]Patting Heads 轻拍牛头【计数】
- bzoj1674 [Usaco2005]Part Acquisition
- USACO 木瓜的丛林