螺旋折线 | 第九届蓝桥杯省赛C++B组

如下图所示的螺旋折线经过平面上所有整点恰好一次。

螺旋折线 | 第九届蓝桥杯省赛C++B组_第1张图片

对于整点 (X,Y),我们定义它到原点的距离 dis(X,Y) 是从原点到 (X,Y) 的螺旋折线段的长度。

例如 dis(0,1)=3,dis(−2,−1)=9

给出整点坐标 (X,Y),你能计算出 dis(X,Y) 吗?

输入格式

包含两个整数 X,Y。

输出格式

输出一个整数,表示 dis(X,Y)。

数据范围

−109≤X,Y≤109

输入样例:
0 1
输出样例:
3
题解:

        数学计算题目,也就是找规律。

        直接讲思路,给定的x和y,其中绝对值较大的数控制大数乘法,较小的数控制左右偏移。

        不好理解可以看下面的表:

X Y X Y
取值 -1 1 1 -1
增加量 +1 +2 +2 +2
取值 -2 2 2 -1
增加量 +3 +4 +4 +4
取值 -3 3 3 -3
增加量 +5 +6 +6 +6
取值 -4 4 4 -4
增加量 +7 +8 +8 +8

        解释:其中取值为X和Y中绝对值较大的数,而属性的‘X’和‘Y’代表这个较大的数在X还是Y上。其中的偏移量是零开始,一步一步累加到目标值的中间值。

         所以,第一步:找出X和Y的绝对值最大值记为N,然后取N-1,求其累加和即:

(((1+N-1)*(N-1))/2)*8-1

        第二步:这只求出到前一个节点的步数,对照上表的分布,发现,除了第一列,其他列的增加量都是abs(N)*2,直接判断并累加。

        第三步:计算偏移量,除去这个绝对最大值的另一项即为偏移量,发现一个螺旋的四个边,在左和上的边是加上偏移量为答案值,例:当取(-2,1)时,刚才计算到(-2,0)的步数是10,发现-2在左边,即X轴的-2,则增加偏移量,10+1=11即为答案。

        而右边和下边则相反,判断计算即可。

        注意:1.第一步判断绝对值最大要一定取等号,因为默认是x轴最大,但是当出现类似(-2,-2)这样在转折处的点,要取y轴的-2才是正确解。

        2.一定所有都开long long int。

代码:
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
typedef long long int ll;

long long int x=0,y=0;

long long int check1(long long int t,long long int num){
    long long int a=0;
    if(t==0 && num<0){
        a=num*(-1)*2-1;
    }
    else if(t==0 && num>=0){
        a=num*6-1;
    }
    else if(t==1 && num<0){
        a=num*(-1)*8-1;
    }
    else if(t==1 && num>=0){
        a=num*4-1;
    }
    return a;
}

long long int check2(long long int t,long long int num,long long int num2){
    if(t==0 && num<0){
        return num2;
    }
    else if(t==0 && num>=0){
        return (-1)*num2;
    }
    else if(t==1 && num<0){
        return (-1)*num2;
    }
    else if(t==1 && num>=0){
        return num2;
    }
}

int main(){
    cin >> x >> y;
    long long int t=0,num=x,num2=y;
    if(abs(x)<=abs(y)){
        t=1;num=y;num2=x;
    }
    long long int ans=0;
    long long int a=abs(num)-1;
    ans=(((1+a)*a)/2)*8-a;
    ans+=check1(t,num);
    ans+=check2(t,num,num2);
    cout << ans << "\n";
}

你可能感兴趣的:(蓝桥杯,c++,算法)