题目链接

Problem Description
甜甜从小就喜欢画图画,最近他买了一支智能画笔,由于刚刚接触,所以甜甜只会用它来画直线,于是他就在平面直角坐标系中画出如下的图形:

甜甜的好朋友蜜蜜发现上面的图还是有点规则的,于是他问甜甜:在你画的图中,我给你两个点,请你算一算连接两点的折线长度(即沿折线走的路线长度)吧。

Input
第一个数是正整数N(≤100)。代表数据的组数。
每组数据由四个非负整数组成x1,y1,x2,y2;所有的数都不会大于100。

Output
对于每组数据,输出两点(x1,y1),(x2,y2)之间的折线距离。注意输出结果精确到小数点后3位。

Sample Input
5
0 0 0 1
0 0 1 0
2 3 3 1
99 99 9 9
5 5 5 5

Sample Output
1.000
2.414
10.646
54985.047
0.000

分析:
看着题目好像跟吓人的样子,但是仔细观察的话就可以发现其中的规律,因为题目上明确给出了所要求的都是整数点之间的距离,也就相当于大大缩小了题目的难度。

我们首先来看那条从右下角往左上角走的直线,其实这条线上除了两个位于x轴和y轴的端点以外是没有整数点的,直接可以计算这天线段的长度,相当于一个以j和(j-1)为直角边的直角三角形的斜边。(j为位于y轴上的点的纵坐标)。

再看从右上到左下的直线,横坐标i减一,就相当于变换了一个整数点,所以到该点的直线的长度可以用建挨着到的右上角的点的直线的长度加上一个以1为两条直角边的之间三角形的斜边长度。

代码:

#include<stdio.h>
#include<iostream>
#include<math.h>
using namespace std;
double len[250][250];
int main()
{
    len[0][0]=0;
    for(int j=1; j<200; j++)
    {
        int temp=j-1;
        len[0][j]=len[j-1][0]+sqrt((1.0*j*j)+(1.0*(j-1)*(j-1)));
        //先加上那条从右下到左上的线段的长度,需要明白一点就是这条线上除了两个端点之外是没有整数点的
        for(int i=1; i<=j; i++)
        {
            //从左上方开始向右下方计数,该直线上横坐标每差一个单位长度就是一个整数点
            len[i][temp]=len[i-1][temp+1]+sqrt(2.0);
            temp--;
        }
    }
    int t,x1,y1,x2,y2;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        printf("%.3lf\n",fabs(len[x1][y1]-len[x2][y2]));
    }
    return 0;
}
posted on 2018-04-06 10:34  渡……  阅读(252)  评论(0编辑  收藏  举报