螺旋折线(找规律解决问题)

问题描述:

对于如下图所示的图形,该螺旋折线经过平面上所有整点恰好一次。
对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。
例如dis(0, 1)=3, dis(-2, -1)=9
给出整点坐标(X, Y),你能计算出dis(X, Y)吗?
螺旋折线示意图

分析:

这个图形是有规律而循的,只需要找到它的规律,便可以解决类似问题。这类问题也是在编程时最喜欢遇到的问题,言简意赅,所求明确,找出规律,列出通式,由特殊到一般。

由该图可以看出两个坐标轴上的整点是特殊点,寻找规律,列出通式,很容易解决问题。而且都是整点,也就是坐标都是整数,有正有负,但是没有浮点数,比较简单。

1以y轴为参考点

当y >= 0 时:

首先找出几个特殊点:
dis(0,0) = 0;
dis(0,1) = 1 + 1 + 1;
dis(1,1) = 1 + 1 + 1 +1;
dis(0,2) = 1 + 1 + 2 + 2 + 3 + 3 + 2;
dis(2,2) = 1 + 1 + 2 + 2 + 3 + 3 + 2 + 2;
dis(0,3) = 1 + 1 + 2 + 2 + 3 + 3 + 4 + 4 + 5 + 5 + 3;
dis(3,3) = 1 + 1 + 2 + 2 + 3 + 3 + 4 + 4 + 5 + 5 + 3 + 3;
(其余式子也是这个规律)
规律为 两个以2y - 1为通式的等差数列的前n项和再加上y再加X;
即dis = (2 * y) * (2 * y - 1) + y + x;

当y < 0 时:

同理可得:
dis(0,-1) = 1 + 1 + 2 + 2 + 1;
dis(-1,-1) = 1 + 1 + 2 + 2 + 1 - (-1);
dis(0,-2) = 1 + 1 + 2 + 2 + 3 + 3 + 4 + 4 + 2;
dis(-2,-2) = 1 + 1 + 2 + 2 + 3 + 3 + 4 + 4 + 2 - (-2);
dis(0,-3) = 1 + 1 + 2 + 2 + 3 + 3 + 4 + 4 + 5 + 5 + 6 + 6 + 3;
dis(-3,-3) = 1 + 1 + 2 + 2 + 3 + 3 + 4 + 4 + 5 + 5 + 6 + 6 + 3 - (-3) ;
首先对y取绝对值,dis为两个以2|y|为通式的等差数列前n项和再加上|y|减去x;
即:dis = (2 * y) * (2 * y + 1) + y - x;

以x轴为参考点:

以x轴为参考点也是通过找几个点找出其存在的规律,当以x轴为参考点时也要考虑y的正负,分情况讨论。
在此不讨论这种情况。

代码:

#include<iostream>
#include<cmath>
using namespace std;
int dis(int x, int y)                           //以y轴上的点为关键点
{
	int dis;                                       //距离
	if (y >= 0)                                 //从(0,0)点开始
	{
		dis = (2 * y) * (2 * y - 1) + y + x; 
	}
	else
	{
		y = abs(y);                             //绝对值
		dis = (2 * y) * (2 * y + 1) + y - x;
	}
	return dis;
}
int main()
{
	int x, y;
	cin >> x;
	cin >> y;
	cout << dis(x, y) << endl;
	return 0;
}

猜你喜欢

转载自blog.csdn.net/Crazy__1/article/details/88604778