*第一次写题解,不好的地方佬们轻喷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;
}