标签:poj1870
题意:首先给的图不是很清楚 为了好说明 用下图示范
如图 这是一个蜂窝 1在中间 然后依次旋转扩散开来 (每个数字代表一个小孔) 然后给你两个数字 让你求出这两孔之间的最小距离;
分析: 首先建个坐标系(二维的) 把每个孔都坐标化 如图
PS:这个横纵坐标轴可以随意 设置
接下来求小孔的坐标, 由第一个图我们可以知道第一个小孔周围是6个孔 再往外是12,24。。。 所以我们可以根据等差求和公式求出 所求小孔在第几圈 ,并且由第二个图我们可以发现第p圈的最后一个孔的坐标为(p,0),所以我们也可以求出所求小孔在第p圈的第几个位置(假设位置为t)。然后从上一圈的最后一点,即(p-1,0)走到目的点,首先应在2方向(1往2的方向)上走1步,再沿3方向(1往3方向)走p-1步,其余的5个方向都走p步,此外每走一次,t就要减去相应的值,当t=0时,就可以退出循环得到坐标。
最后一步就是就是根据两个孔的坐标求距离 无非两种情况:一种是横坐标差的绝对值加上纵坐标差的绝对值。另一种是在他们之间取最大值即可。
代码:
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#include <vector>
#include <queue>
#include <ctime>
#include <stdlib.h>
#include <string.h>
#define N 10000
#define InF 10000000
#define minn -999999999
#define maxn 999999999
#define mem(a) memset(a,0,sizeof(a))
#define LL long long
using namespace std;
double PI=acos(-1.0);
double x;
int a,b,t,p,xx,yy,i;
int solve(int n)//求坐标
{
x=(sqrt(12*(double)n-3)-3)/6;
p=(int)x;
if(3*p*p+3*p+1!=n)
{
t=n-(3*p*p+3*p+1);
p++;
xx=p-1;
yy=0;
while(t)
{
t--;
yy++;
for(i=1; i<=p-1&&t; i++,t--)
xx--,yy++;
for(i=1; i<=p&&t; i++,t--)
xx--;
for(i=1; i<=p&&t; i++,t--)
yy--;
for(i=1; i<=p&&t; i++,t--)
xx++,yy--;
for(i=1; i<=p&&t; i++,t--)
xx++;
for(i=1; i<=p&&t; i++,t--)
yy++;
}
return 1;
// printf("%d %d\n",xx,yy);
}
else
return 0;
//printf("%d 0\n",p);
}
int main()
{
while(scanf("%d%d",&a,&b)!=EOF,a||b)
{
int x1,x2,y1,y2;
if(solve(a))
{
x1=xx;
y1=yy;
}
else
{
x1=p;
y1=0;
}
if(solve(b))
{
x2=xx;
y2=yy;
}
else
{
x2=p;
y2=0;
}
// cout<<abs(x1-x2)+abs(y1-y2)<<endl;
int ans=0;
if((x1-x2)*(y1-y2)<=0)//两种可能
{
ans = max(abs(x1-x2),abs(y1-y2)) ;
}
else
{
ans = abs(x1-x2)+abs(y1-y2) ;
}
printf("The distance between cells %d and %d is %d.\n",a,b,ans);
}
return 0;
}
标签:poj1870
原文地址:http://blog.csdn.net/bigsungod/article/details/43918175