题意
讨论区里的翻译挺不错的,可以去看看。
大致意思是给定了一种坐标系和一种编号方法,将每个编号转化为对应的坐标。
分析
大佬们的奇怪思路我不理解,不过这个数据范围决定了它就是一道橙题。
保证每个编号小于 1 0 5 10^5 105,我预处理一下不就完事了吗。
具体如何模拟呢?
最开始的 8 8 8 个不太好处理规律,直接填写答案,从第九个开始分为 6 6 6 个方向。
- 左上方,横坐标减一。
- 上方,纵坐标减一。
- 右上方,横坐标加一,纵坐标减一。
- 右下方,横坐标加一。
- 下方,纵坐标加一。
- 左下方,横坐标减一,纵坐标加一。
如果横坐标或纵坐标为零或者横纵坐标相加为零,就变换方向。
如果纵坐标为零,横坐标大于零,就说明这一圈结束了,需要停止变换方向一次,过了这个编号再转方向。
代码
#include<bits/stdc++.h>
using namespace std;
int a1,a2,b1,b2,a[1000005],b[1000005],t=1,da[10]={
0,-1,-1,0,1,1},db[10]={
1,1,0,-1,-1,0},n,f;
int main()
{
a[1]=a[2]=a[5]=b[1]=b[4]=b[7]=0;
a[3]=a[4]=b[5]=b[6]=-1;
a[6]=a[7]=b[2]=b[3]=1;
a[8]=b[8]=1;
a1=1;
b1=1;
f=0;
for(int i=9;i<1000001;i++)
{
a2=a1+da[t];
b2=b1+db[t];
a1=a2;
a[i]=a2;
b1=b2;
b[i]=b2;
if(f)
{
f=0;
t++;
}
if(a1>0&&b1==0)
{
f=1;
continue;
}
if(a1==0||b1==0||a1+b1==0)t=(t+1)%6;
}
while(~scanf("%d",&n))cout<<a[n]<<" "<<b[n]<<endl;//注意多测。
return 0;
}