P8668 螺旋折线
___w
·
·
题解
P8668 [蓝桥杯 2018 省 B] 螺旋折线
题意简述
- 对于整点 (x,y),定义它到原点的距离 \text{dis}(x,y) 是从原点到 (x,y) 的螺旋折线段的长度。
- 给出整点坐标 (x,y),求 \text{dis}(x,y)。
题目分析
做到这题看到这个大蚊香瞬间蚌埠住了,这题也就随随便便分类讨论罢了。
如图所示,我们可以将这个“大蚊香”分为上下左右四个部分。定义 n=\max(\left|x\right|,\left|y\right|)。
我们发现,像类似 \text{dis}(x,-x)(其中 x\geqslant0)的值为左右部分的和和上下部分的和,为:
那么我们就可以分别讨论点 $(x,y)$ 分别位于哪个部分,再对 $d$ 增减。
当 $y\geqslant0$ 且 $\left|x\right|\le y$ 时(即上部分),$\text{dis}(x,y)=d-3n+x$。
当 $y<0$ 且 $y<x\le -y$ 时(即下部分),$\text{dis}(x,y)=d+n-x$。
当 $x\geqslant0$ 且 $\left|y\right|\le x$ 时(即右部分),$\text{dis}(x,y)=d-n-y$。
当 $x<0$ 且 $x<y\le -x$ 时(即左部分),$\text{dis}(x,y)=d-5n+y$。
这些结论可以自己在草稿纸上推一推,这里就不展开详细说明了。有了结论,代码也就简单了。
#### 代码
记得开 ```long long```。
```cpp
#include <bits/stdc++.h>
using namespace std;
long long x, y, n, d;
int main() {
cin >> x >> y;
n = max(abs(x), abs(y)), d = 2*n*(2*n+1);
if (y >= 0 && abs(x) <= y) cout << d-3*n+x;//上部分
else if (y < 0 && y < x && x <= -y) cout << d+n-x;//下部分
else if (x >= 0 && abs(y) <= x) cout << d-n-y;//右部分
else if (x < 0 && x < y && y <= -x) cout << d-5*n+y;//左部分
return 0;
}
```