*第一次写题解,不好的地方佬们轻喷QAQ

好像有些人(包括我)对文字题解有些困惑,分享一下我的做法,感觉我的思路不会太难理解(吧)

首先,这个路线最终绕出来的形状都是正方形,大胆猜测t为平方数的时候一定有特殊的固定位置,不难发现,t为奇数平方数、t为偶数平方数分别在y = x 和 y = x - 1两条直线上,根据正方形的边长,可以简单确定平方数所在的坐标。例如 t = 1,坐标为(0,0),t = 9,坐标(1,1),t = 4,坐标(0,-1),t = 16,坐标(-1,-2)……后边都一样符合规律,不再多做列举。在此就可以反推,坐标可以用正方形边长计算得出:

正方形边长n = sqrt(t);

t为奇数,即t % 2 == 1时,x = t / 2, y = t / 2;

t为偶数,即t % 2 == 0时,x = 1 - n/2, y = -n/2;

接着就可以判定所求的时间t在哪两个平方数所构成的L型折线上了。创建res变量存储从较小平方数出发,最长的路径即:

n为奇数时:右移一个单位(x ++),然后下移n个单位,最后左移n个单位。

n为偶数时:左移一个单位(x --),然后上移n个单位,最后右移n个单位。两种情况的路线方向是刚好相反的。

模拟到res为0的结果,就是t时刻的坐标。

#include<bits/stdc++.h>
using namespace std;
using ll = long long;    //奇数的平方:x == y 偶数的平方: y = x - 1
void solve(){
    ll t, n;
    cin >> t;
    n = sqrt(t);
    while((n + 1) * (n + 1) < t) n ++;
    while(!(n * n <= t && (n + 1) * (n + 1) > t))
        n --;
    if(n % 2){
        ll res = t - n * n, x = n / 2, y = n / 2;
        //cout << "TEST: " << x << " " << y << " " << n << " " << res << '\n';
        if(!res){
            cout << x << " " << y << '\n';
        }
        else{
            x ++, res --;
            if(res){
                y -= min(n, res);
                res -= min(n, res);
            }
            if(res){
                x -= min(n, res);
                res -= min(n, res);
            }
            cout << x << " " << y << '\n';
        }
    }
    else{
        ll res = t - n * n, x = 1 - n / 2, y = -n / 2;
        if(!res){
            cout << x << " " << y << '\n';
        }
        else{
            res --;
            x --;
            if(res){
                y += min(n, res);
                res -= min(n, res);
            }
            if(res){
                x += min(n, res);
                res -= min(n, res);
            }
            cout << x << " " << y << '\n';
        }
    }
}

int main(){
    ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
    int T;
    cin >> T;
    while(T --)
        solve();
    
    return 0;
}