【蓝桥杯2018JavaB】螺旋折线

如图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;
	}
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值