usaco Chapter 3 section 3.3 Camelot
来源:互联网 发布:ac尼尔森数据分析2016 编辑:程序博客网 时间:2024/05/17 10:39
/*
CamelotIOI 98
Centuries ago, King Arthur and the Knights of the Round Table used to meet every year on New Year's Day to celebrate their fellowship. In remembrance of these events, we consider a board game for one player, on which one chesspiece king and several knight pieces are placed on squares, no two knights on the same square.
This example board is the standard 8x8 array of squares:
The King can move to any adjacent square from to as long as it does not fall off the board:
A Knight can jump from to , as long as it does not fall off the board:
During the play, the player can place more than one piece in the same square. The board squares are assumed big enough so that a piece is never an obstacle for any other piece to move freely.
The player's goal is to move the pieces so as to gather them all in the same square - in the minimal number of moves. To achieve this, he must move the pieces as prescribed above. Additionally, whenever the king and one or more knights are placed in the same square, the player may choose to move the king and one of the knights together from that point on, as a single knight, up to the final gathering point. Moving the knight together with the king counts as a single move.
Write a program to compute the minimum number of moves the player must perform to produce the gathering. The pieces can gather on any square, of course.
*/
/*
ID: niepeng1
LANG: C++
TASK: camelot
不得不承认,我又参考了别人的程序。这次题目完全没有思路。最后看了题解发现国王搭载骑士的地点有限制只能在-2,+2 row col之间
最后发现时一次计算所有节点间的骑士步数,然后枚举结束点。计算没有国王的距离,最后再加上搭载国王的最短增加的步数就可以得到结果了。
*/
#include <iostream>
using namespace std;
#define MaxR 35
#define MaxC 30
FILE *in,*out;
int minSteps[MaxR][MaxC][MaxR][MaxC];
int visited[MaxR][MaxC];
int path[8][2]={
-1,-2,
-2,-1,
-2, 1,
-1, 2,
1, 2,
2, 1,
2,-1,
1,-2
};
struct lovekid{
int row;//行
int column;//列
}King,Knight[MaxR*MaxC],queue[MaxR*MaxC];
int R,C,cnt,ans=1<<30;
void Init()
{
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++)
for(int ii=1;ii<=R;ii++)
for(int jj=1;jj<=C;jj++)
minSteps[i][j][ii][jj]=1<<25;
}
void Refresh()
{
for(int i=1;i<=R;i++)
for(int j=1;j<=C;j++)
visited[i][j]=false;
}
int KingWay(int r,int c)
{
int row=King.row-r;
if(row<0)
row=-row;
int col=King.column-c;
if(col<0)
col=-col;
return row>col?row:col;
}
void Bfs()
{
int r,c,k,left,right,preR,preC,currentR,currentC;
Init();
for(r=1;r<=R;r++)
for(c=1;c<=C;c++){
Refresh();//更新访问标记
left=right=0;//初始化数据
queue[right].column=c;
queue[right++].row=r;
visited[r][c]=true;
minSteps[r][c][r][c]=0;
while(left<right){
preR=queue[left].row;preC=queue[left++].column;
for(k=0;k<8;k++){
currentR=preR+path[k][0];currentC=preC+path[k][1];
if(currentR>0&¤tR<=R&¤tC>0&¤tC<=C&&
!visited[currentR][currentC]){
queue[right].column=currentC;
queue[right++].row=currentR;
minSteps[r][c][currentR][currentC]=minSteps[r][c][preR][preC]+1;
visited[currentR][currentC]=true;
}
}
}
}
}
void Solve(){
int i,j,k,total,diffrence,r,c,kr,kc,tmp;
bool cut;//剪枝,剪掉骑士不能到达的格子
Bfs();
for(i=1;i<=R;i++)
for(j=1;j<=C;j++){//枚举终点
total=0;
cut=false;
for(k=0;k<cnt;k++)
if(minSteps[Knight[k].row][Knight[k].column][i][j]>=(1<<25)){
cut=true;//遍历所有的骑士节点,如果有一个不能到,就放弃该节点
break;
}
else total+=minSteps[Knight[k].row][Knight[k].column][i][j];
if(cut||total>ans)continue;/*剪掉不能到达的格子和还没算王的路径已经大于或目前最有解的值格子*/
diffrence=KingWay(i,j);
//total存储当前不包含王的所有骑士汇聚到目标节点的距离
for(r=-2;r<=2;r++)//最优解在的范围是王的坐标+-2
for(c=-2;c<=2;c++){
kr=King.row+r;
kc=King.column+c;
if(kr>0&&kr<=R&&kc>0&&kc<=C)//在边界内
for(k=0;k<cnt;k++){//遍历所有骑士,如果求最小的载王去目的地点的距离
tmp=minSteps[Knight[k].row][Knight[k].column][kr][kc]+
minSteps[kr][kc][i][j]+KingWay(kr,kc)-
minSteps[Knight[k].row][Knight[k].column][i][j];
if(diffrence>tmp)//difference存储王直接走到目标节点的步数
diffrence=tmp;
}
}
total+=diffrence;
if(ans>total)
ans=total;
}
fprintf(out,"%d/n",ans);
}
void Read(){//读入数据
in=fopen("camelot.in","r");
out=fopen("camelot.out","w");
char str[2];
int input;
fscanf(in,"%d%d",&R,&C);
fscanf(in,"%s%d",str,&input);
King.row=input;King.column=str[0]-'A'+1;//王的坐标
while(fscanf(in,"%s%d",str,&input)!=EOF){//骑士的坐标
Knight[cnt].row=input;Knight[cnt++].column=str[0]-'A'+1;
}
}
int main()
{
Read();
Solve();
return 0;
}
- usaco Chapter 3 section 3.3 Camelot
- USACO Section 3.3 Camelot
- USACO 3.3.3 camelot
- USACO 3.3.3 Camelot
- USACO 3.3.3 Camelot
- USACO 3.3 Camelot (camelot)
- usaco Chapter 3 section 3.3 Shopping Offers
- usaco Chapter 3 section 3.3 A game
- USACO Section 3.3 Camelot - 略恶心的BFS
- USACO-Section 3.3 Camelot (最短路&&枚举)
- usaco Chapter 3 section 3.3 Riding the Fences
- usaco Chapter 3 section 3.3 Home on the Range
- USACO section Camelot(枚举+队列优化)
- USACO 3.3 Camelot
- usaco Chapter 3 section 3.1 Agri-Net
- usaco Chapter 3 section 3.1 Humble Numbers
- usaco Chapter 3 section 3.1 Score Inflation
- usaco Chapter 3 section 3.1 Shaping Regions
- Java学习路线【转载自topinking老兄的blog】.txt
- linux 图形库编程资源
- JAVA对象的排序
- 用户登录后,跳转到另一个action页面,但是刷新页面,会重新登录怎么办呀?
- 新书预告《Windows Powershell 2.0应用编程最佳实践》即将出版
- usaco Chapter 3 section 3.3 Camelot
- C语言地址传递和值传递简析
- Javascript 闭包
- 总结JDBC连接SQLServer的错误Error establishing socket(转)
- 商务先锋2010
- 乒乓4
- 人多未必力量大
- 网上教工教学评分系统
- Oracle 控制文件 说明