蓝桥杯第九届省赛JAVA真题----螺旋折线

标题:螺旋折线

如图p1.pgn所示的螺旋折线经过平面上所有整点恰好一次。
这里写图片描述
对于整点(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

资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗 < 1000ms
请严格按要求输出,不要画蛇添足地打印类似:“请您输入…” 的多余内容。
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。

解析:按象限划分四个部分,以拐点为突破口。比赛的时候想到了,但是一紧张就没有静下心来好好分析,罪过罪过。
根据给定坐标求解拐点是比较简单的,我们对于每个点都求出它x和y中较大的那个值,然后我们可以得到:
第一象限的拐点坐标——dx = max(abs(x), abs(y)),dy = dx
第二象限的拐点坐标——dx = -max(abs(x), abs(y)),dy = -dx
第三象限的拐点坐标——dx = -max(abs(x), abs(y)),dy = dx - 1
第四象限的拐点坐标——dx = max(abs(x), abs(y)),dy = -dx

假定拐点坐标为(dx, dy),我们有
第一象限的拐点的dfs()——(abs(dx)+abs(dy))^2
第二象限的拐点的dfs()——(abs(dx)+abs(dy)) * (abs(dx)+abs(dy) - 1)
第三象限的拐点的dfs()——(abs(dx)+abs(dy))^2
第四象限的拐点的dfs()——(abs(dx)+abs(dy)) * (abs(dx)+abs(dy) + 1)

之后根据给定坐标(x, y)与拐点坐标(dx, dy)的关系就可以轻松的解出来了。
还要特别注意给定坐标中x或y等于0的情况,这里我把四种情况分别归到了四个象限中

这样求解这个问题最后时间复杂度为O(1)

import java.util.Scanner;

public class Main {
    static int x, y;
    static int df = 0;
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        x = in.nextInt();
        y = in.nextInt();

        if (x > 0 && y >= 0) {
            int dx = Math.max(x, y);
            int dy = dx;
            df = (dx + dy) * (dx + dy);
            if (x < dx) {
                df -= (dx - x);
            }
            if (y < dy) {
                df += (dy - y);
            }
        } else if (x >= 0 && y < 0) {
            int dx = Math.max(Math.abs(x), Math.abs(y));
            int dy = -dx;
            df = (dx + Math.abs(dy)) * (dx + Math.abs(dy) + 1);
            if (x < dx) {
                df += (dx - x);
            }
            if (y > dy) {
                df -= (y - dy);
            }
        } else if (x < 0 && y <= 0) {
            int dx = -Math.max(Math.abs(x), Math.abs(y));
            int dy = dx + 1;
            df = (Math.abs(dx) + Math.abs(dy)) * (Math.abs(dx) + Math.abs(dy));
            if (x > dx) {
                df -= (x - dx);
            }
            if (y > dy) {
                df += (y - dy);
            }
        } else  if (x <= 0 && y > 0) {
            int dx = -Math.max(Math.abs(x), Math.abs(y));
            int dy = -dx;
            df = (Math.abs(dx) + Math.abs(dy)) * (Math.abs(dx) + Math.abs(dy) - 1);
            if (x > dx) {
                df += (x - dx);
            }
            if (y < dy) {
                df -= (y - dy);
            }
        }
        System.out.println(df);
    }
}
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值