如图p1.png所示的螺旋折线经过平面上所有整点恰好一次。
对于整点(X, Y),我们定义它到原点的距离dis(X, Y)是从原点到(X, Y)的螺旋折线段的长度。
例如dis(0, 1)=3, dis(-2, -1)=9
给出整点坐标(X, Y),你能计算出dis(X, Y)吗?
【输入格式】
X和Y
对于40%的数据,-1000 <= X, Y <= 1000
对于70%的数据,-100000 <= X, Y <= 100000
对于100%的数据, -1000000000 <= X, Y <= 1000000000
【输出格式】
输出dis(X, Y)
【输入样例】
0 1
【输出样例】
3
还是先提供我自己的思路,这种题我觉得思路很清晰的,因为方向是固定的,这里找到这样的规律:
- 方向顺序是固定的。向左->向上->向右-向下,一直这样循环
- 每转换两次方向,在一个方向上的线的长度会加一
用这两个规律就足够了,让点从0开始找,while(true),找到了就打印和结束
public class Main{
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
int sum=0,a=0,b=0,len=1,lencount=0;
int x=sc.nextInt();
int y=sc.nextInt();
while(true) {
while(lencount<len) {
a--;lencount++;sum++;if(a==x&&b==y) {System.out.println(sum);return;}
}lencount=0;
while(lencount<len) {
b++;lencount++;sum++;if(a==x&&b==y) {System.out.println(sum);return;}
}lencount=0;
len++;
while(lencount<len) {
a++;lencount++;sum++;if(a==x&&b==y) {System.out.println(sum);return;}
}lencount=0;
while(lencount<len) {
b--;lencount++;sum++;if(a==x&&b==y) {System.out.println(sum);return;}
}lencount=0;
len++;
}
}
}
接下来提供别人的思路
dis(0, 1)=3
dis(-2, -1)=9
dis(1, 1)=4
暴力解法:超时 -10^9 ≤ x、y ≤ 10^9 -> 爆int x↓y↑、x↑y↓、x↓y↑、x↑y↓
public class A07_螺旋折线 {
// 以 右下角 对角线上的点 为 参照点,测算给定的点到参照点要走的距离
public static void main(String[] args) throws FileNotFoundException {
Scanner sc = new Scanner(System.in);
long X = sc.nextLong(), Y = sc.nextLong();
long d = 0; // 距离
long n = 0; // 第几圈
if (Y > 0 && Math.abs(X) <= Y) { // 点在上面的横线上
n = Y; // 等差数列有多少项? Y项
d = (Y - X) + (2 * Y); // X的最大值是Y,第一、四象限的距离---2Y
} else if (X > 0 && Math.abs(Y) <= X) { // 点在最右边的横线上
n = X;
d = Y + X;
} else if (Y <= 0 && X >= Y - 1 && X <= -Y) { // 点在最下边的横线上
n = -Y;
d = -(-Y - X);
} else if (X < 0 && Y >= X + 1 && Y <= -X) { // 点在最左边的横线上
n = -X - 1;
d = -(Y - X - 1 - 2 * X - 1);
}
System.out.println(sum(1L, 2 * n, 1) * 2 - d);
}
/**
* 等差数列求和
*
* @param a0 首项
* @param n 项数
* @param d 公差
* @return
*/
private static long sum(long a0, long n, int d) {
return (2 * a0 + (n - 1) * d) * n / 2;
}
}