题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2073
方法:找规律
思路:这是我觉得水题中比较有水平的一道题目,基本思路是首先找到一个每个点转移到下一个点的规律,规律为,如果纵坐标为0,则下一个点横坐标为0,下一个点纵坐标为当前点横坐标+1,如果当前点纵坐标不是0,那么横+1,纵-1.第二,注意数据给出的情形不是严格按照点的生成规律的,也就是说两个点不一定谁前谁后,所以思路是以原地为基准,求各个点到远点的距离,这样两个距离作差做绝对值可以避免顺序问题。
难点:一些功能函数的编写需要格外小心。
#include<cstdio>
#include<iostream>
#include<cmath>
using namespace std;
int nextPx = 0;
int nextPy = 0;
double getDistance(int ax,int ay,int bx,int by)
{
return sqrt((double(ax)-double(bx))*(double(ax)-double(bx))+(double(ay)-double(by))*(double(ay)-double(by)));
}
void changePoint(int x,int y)
{
if(y == 0)
{
nextPx = 0;
nextPy = x+1;
}
else
{
nextPx = x+1;
nextPy = y-1;
}
//cout<<nextPx<<" "<<nextPy<<"->";
}
double getSum(int x,int y)
{
double sum = 0.0;
if(x == 0 && y == 0)
return sum;
changePoint(0,0);
int prePx = 0;
int prePy = 0;
int flag = 0;
while(!(nextPx == x && nextPy == y))
{
//cout<<nextPx<<" "<<nextPy<<endl;
sum += getDistance(prePx,prePy,nextPx,nextPy);
prePx = nextPx;
prePy = nextPy;
changePoint(prePx,prePy);
//cout<<nextPx<<" "<<nextPy<<"*"<<endl;
//flag++;
}
//cout<<flag<<endl;
sum += getDistance(prePx,prePy,x,y);
return sum;
}
int main()
{
//cout<<getSum(0,1);
int n;
int ax,ay,bx,by;
while(cin>>n)
{
while(n--)
{
cin>>ax>>ay>>bx>>by;
printf("%.3lf\n",abs(getSum(ax,ay)-getSum(bx,by)));
}
}
}