Bzoj 1143
Bzoj 1228

Bzoj 1193

coc youyl posted @ 2015年7月02日 16:24 in bzoj , 604 阅读

题目分类:乱搞,贪心

题意:

给出平面上的两个坐标,从一个开始按照棋子马的移动规则移动,问最小步数。

题解:

大范围贪心,小范围暴力。

注意贪心时要考虑一维极小一维极大的情况,所以要将两步合并为一步进行处理。

程序:

#include<cstdio>
#include<queue>
#include<algorithm>
using namespace std;
int x1,y1;
int x2,y2;
int tx,ty,ans;
const int dir[8][2]={{1,2},{1,-2},{-1,2},{-1,-2},{2,1},{-2,1},{2,-1},{-2,-1}};
int dis[220][220];
inline void bfs()
{
	queue<int>q1,q2;
	q1.push(tx);
	q2.push(ty);
	dis[tx][ty]=ans+1;
	while (!q1.empty())
	{
		x1=q1.front();
		x2=q2.front();
		q1.pop();
		q2.pop();
		for (int i=0;i<8;i++)
		{
			if(x1+dir[i][0]>0&&x1+dir[i][0]<=200&&x2+dir[i][1]>0&&x2+dir[i][1]<=200)
			{
				if(dis[x1+dir[i][0]][x2+dir[i][1]]==0)
				{
					dis[x1+dir[i][0]][x2+dir[i][1]]=dis[x1][x2]+1;
					q1.push(x1+dir[i][0]);
					q2.push(x2+dir[i][1]);
					if(x1+dir[i][0]==50&&x2+dir[i][1]==50)return;
				}
			}
		}
	}
}
inline int abss(int x1)
{
	if(x1>0)return x1;
	return -x1;
}
int main()
{
	scanf("%d %d %d %d",&x1,&y1,&x2,&y2);
	tx=abss(x1-x2);ty=abss(y1-y2);
	while (tx+ty>=50)
	{
		if(tx<ty)swap(tx,ty);
		if(tx-4>2*ty)tx-=4;
		else tx-=4,ty-=2;
		ans+=2;
	}
	tx+=50;
	ty+=50;
	bfs();
	printf("%d\n",(-1)+dis[50][50]);
	return 0;
}

登录 *


loading captcha image...
(输入验证码)
or Ctrl+Enter