百度之星2015 1005 下棋

思路:

对于任意一个格子,设国王到达这个格子至少需要x步,骑士到达这个格子至少需要y步,则:

对于这个格子,

1)国王到达这个格子需要的步数为:x+k步,其中k=0,1,2,3,4,5,...

2)骑士到达这个格子需要的步数为:x+2*k步,其中k=0,1,2,3,4,5,...

然后对1000*1000个格子都算一遍最小相遇的步数,然后再取个最小值就行了。

/*百度之星2015 1005 下棋
  思路:
  对于任意一个格子,设国王到达这个格子至少需要x步,骑士到达这个格子至少需要y步,则:
  对于这个格子,
  1)国王到达这个格子需要的步数为:x+k步,其中k=0,1,2,3,4,5,...
  2)骑士到达这个格子需要的步数为:x+2*k步,其中k=0,1,2,3,4,5,...
  然后对1000*1000个格子都算一遍最小相遇的步数,然后再取个最小值就行了。
 */
#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int N=1005;
const int INF=0x3f3f3f3f;
int n,m,k;
int G[N][N];
struct Pt{
	short x,y;
	Pt(){}
	Pt(short _x,short _y){
		x=_x;
		y=_y;
	}
};

queue<Pt> q;
int dx[]={-2,-1,-2,-1,1,2,2,1};
int dy[]={-1,-2,1,2,-2,-1,1,2};
int _abs(int x){
	if(x<0) return -x;
	return x;
}
int get_t(int x1,int y1,int x2,int y2){
	int dx=_abs(x1-x2);
	int dy=_abs(y1-y2);
	int ret=max(dx,dy);
	if(ret==0) ret=2;
	return ret;
}
bool ok(int x,int y,int x1,int y1){
	if(x>=0 && x<n && y>=0 && y<m && G[x][y]==-1)
		return true;
	return false;
}
void bfs(Pt S,Pt T){
	q.push(S);
	G[S.x][S.y]=0;
	while(!q.empty()){
		Pt now=q.front();
		q.pop();
		for(int i=0;i<8;++i){
			int tmpx=now.x+dx[i];
			int tmpy=now.y+dy[i];
			if(ok(tmpx,tmpy,T.x,T.y)){
				//cout<<tmpx<<' '<<tmpy<<endl;
				q.push(Pt(tmpx,tmpy));
				G[tmpx][tmpy]=G[now.x][now.y]+1;
			}
		}
	}
}

void gao(int x1,int y1,int x2,int y2){
	--x1;
	--y1;
	--x2;
	--y2;
	memset(G,-1,sizeof(G));
	bfs(Pt(x2,y2),Pt(x1,y1));
	//for(int i=0;i<n;++i){
	//	for(int j=0;j<m;++j){
	//		cout<<G[i][j]<<' ';
	//	}
	//	cout<<endl;
	//}
	int ans=INF;
	for(int i=0;i<n;++i){
		for(int j=0;j<m;++j){
			int t=get_t(i,j,x1,y1);
			//cout<<t<<','<<G[i][j]<<' ';
			//if(t<=G[i][j] && G[i][j]<=k)
			if(G[i][j]!=-1){
				if(t<=G[i][j]){
					if(G[i][j]<=k)
						ans=min(ans,G[i][j]);
				}
				else{
					int tmp;
					if((t-G[i][j])%2==0) tmp=t;
					else tmp=t+1;
					if(tmp<=k) ans=min(ans,tmp);
				}
			}
		}
		//cout<<endl;
	}
	if(ans==INF) puts("OH,NO!");
	else printf("%d\n",ans);
}
int main(){
	int T;
	int cas=0;
	scanf("%d",&T);
	while(T--){
		scanf("%d%d%d",&n,&m,&k);
		int x1,y1;
		int x2,y2;
		scanf("%d%d",&x1,&y1);
		scanf("%d%d",&x2,&y2);
		printf("Case #%d:\n",++cas);
		gao(x1,y1,x2,y2);
	}
	return 0;
}

时间: 2024-10-08 21:40:35

百度之星2015 1005 下棋的相关文章

百度之星资格赛1005 下棋 BFS

下棋 Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description N?M的棋盘上有一个受伤的国王与一个要去救援国王的骑士,他们每个单位时间必须同时移动一次寻找对方.如下图所示,黑色的图例表示国王(右)或骑士(左)当前所在的位置,那么灰色的位置表示在一次移动中他们可能到达的位置.国王伤势严重,因此他必须在K个单位时间内得到骑士的救援,否则会挂掉.问国王是否可

百度之星2015资格赛 IP聚合

IP聚合 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 当今世界,网络已经无处不在了,小度熊由于犯了错误,当上了度度公司的网络管理员,他手上有大量的 IP列表,小度熊想知道在某个固定的子网掩码下,有多少个网络地址.网络地址等于子网掩码与 IP 地址按位进行与运算后的结果,例如: 子网掩码:A.B.C.D IP 地址:a.b.c.d 网络地址:

百度之星 2015 初赛(1) 1002 找连续数

找连续数 Accepts: 401 Submissions: 1911 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 小度熊拿到了一个无序的数组,对于这个数组,小度熊想知道是否能找到一个k 的区间,里面的 k 个数字排完序后是连续的. 现在小度熊增加题目难度,他不想知道是否有这样的 k 的区间,而是想知道有几个这样的 k 的区间. Input

百度之星 2015 复赛 1001 (数长方形)

数长方形 Accepts: 595 Submissions: 1225 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Problem Description 小度熊喜欢玩木棒.一天他在玩木棒的时候,发现一些木棒会形成长方形.小度熊可能是处女座吧,他只会将木棒横竖摆放,这样会形成很多长方形.现在给你一些横竖摆放的木棒,请你帮小度熊数一数形成了多少个长方形. 为了简化题目,一个木棒的端

HDU5262 15年百度之星复赛1005 最强密码(神奇的dp)(好题)

Problem Description 由于近来密码库被盗的现象层出不穷,度度熊决定为自己的账号找一个最强密码.在研究了密码库很久之后,它总结出了一个规律:密码库中的所有密码都是一个"密码生成串"的子序列(某个序列的子序列是从最初序列通过去除某些元素但不破坏余下元素的相对位置(在前或在后)而形成的新序列). 经过强大的计算集群夜以继日的工作,度度熊得到了这个"密码生成串".现在它希望找到一个"最强密码",不是这个"密码生成串"

百度之星2015资格赛 放盘子

放盘子 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 小度熊喜欢恶作剧.今天他向来访者们提出一个恶俗的游戏.他和来访者们轮流往一个正多边形内放盘子.最后放盘子的是获胜者,会赢得失败者的一个吻.玩了两次以后,小度熊发现来访者们都知道游戏的必胜策略.现在小度熊永远是先手,他想知道他是否能获胜. 注意盘子不能相交也不能和多边形相交也不能放在多边形外

百度之星2015资格赛 列变位法解密

列变位法解密 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 列变位法是古典密码算法中变位加密的一种方法,具体过程如下 将明文字符分割成个数固定的分组(如5个一组,5即为密钥),按一组一行的次序整齐排列,最后不足一组不放置任何字符,完成后按列读取即成密文. 比如: 原文:123456789 密钥:4 变换后的矩阵: 1234 5678 9xxx

百度之星2015资格赛 大搬家

大搬家 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Problem Description 近期B厂组织了一次大搬家,所有人都要按照指示换到指定的座位上.指示的内容是坐在位置ii上的人要搬到位置jj上.现在B厂有NN个人,一对一到NN个位置上.搬家之后也是一一对应的,改变的只有位次. 在第一次搬家后,度度熊由于疏忽,又要求大家按照原指示进行了一次搬家.于是,机智的它想到:再按这个

(最小费用流)hdu 6118(2017百度之星初赛B 1005) 度度熊的交易计划

度度熊的交易计划 Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 260    Accepted Submission(s): 83 Problem Description 度度熊参与了喵哈哈村的商业大会,但是这次商业大会遇到了一个难题: 喵哈哈村以及周围的村庄可以看做是一共由n个片区,m条公路组成的地区. 由于生产能力的区别,第i个片