題干
小W是一個宅男,喜歡發呆,并幻想一些不切實際的事情。今天,小W又開始做他的白日夢了。他夢見他被困在了一條隧道里,周圍漆黑一片。作為一個宅男,小W自然地掏出了手機,打開定位系統,確定了他的位置。又由此在網上搜索到了關于隧道的信息。這條隧道是由一個點向外,呈六角螺旋形展開,并且沒有其他的支路。*小的一圈每條邊的長度都是1米,邊長向外依次增大到2,3.米,如下圖所示。
輸入數據以一個整數T<104開頭,表示測試數據組數。以下每行為一組測試數據,包括4個整數X1,Y1,X2,Y2,描述了小W所在的位置和出口位置的坐標。所有坐標的**值不超過1018,并保證答案不超出64位有符號整數的表示范圍。
輸出對于每組測試數據輸出一行,一個整數,表示小W所在的位置和出口的距離。
Sample Input
Sample Output
分析
模擬題,我的方案是先計算起點和終點所在的層數,每層的長度是一個公差為6的等差數列,考慮數列求和公式。
這里要考慮兩種情況。
**種情況:起點為(0,0),終點為任意。先用求和公式計算終點所在圈以內所有圈的長度總和,然后加上終點所在圈的位置長度,終點的位置長度至少要分4種情況。
第二種情況:起點任意,終點在起點以外的任意位置,先求起點和終點之間圈的長度總和,然后加上終點所在圈的距離,加上起點所在該圈的長度,再減去起點所在圈的位置長度。
注意:本題起點和終點是可以對換位置的,若是對換位置,則上面方法的計算結果為負數,需要取**值(不能用abs,abs只適用于int)。
各圈分解見下圖所示,同色代表為同一圈
題解
#include"bits/stdc++.h"
using namespace std;
typedef long long ll;
ll count_layer(ll x,ll y,ll layer){
if(x<0&&y==0) return 0;
else if(x<=0&&y<0){
if(x0&&y<=0) return layer*3+y;
else{
if(y>T;
ll i;
for(i=0;i>x1>>y1>>x2>>y2;
ll absx1 = x1>0 ? x1:-1*x1;
ll absy1 = y1>0 ? y1:-1*y1;
ll absx2 = x2>0 ? x2:-1*x2;
ll absy2 = y2>0 ? y2:-1*y2;
ll layer_position = absx1>absy1 ? absx1:absy1;
ll layer_outlet = absx2>absy2 ? absx2:absy2;
if(x1>0&&y1<0) layer_position = absx1+absy1;
else if(x10) layer_position =absx1+absy1-1;
if(x2>0&&y2<0) layer_outlet = absx2+absy2;
else if(x20) layer_outlet =absx2+absy2-1;
if(layer_position==layer_outlet&&layer_position==0){
cout<<0<0){
ll n = layer_outlet-1;
ll ans = 7*n+n*(n-1)*3+1;
ans+=count_layer(x2,y2,layer_outlet);
ans>0 ? ans:-1*ans;
cout< cout< } } return 0; }