poj 2265 Bee Maja
题目的意思很容易理解.就是找两个不同坐标的对应关系.下面的思路转自POJ的论坛
首先,记由1到2的方向记为2,1到3的方向记为3……1到7的方向记为7,他们分别是:(0,1),(-1,1),(-1,0),(0,-1),(1,-1),(1,0);这些规律不仅对于1的周围六个方向有效,对于所有的点都是有效的。然后记1所在为圈1,2..7为圈1,8..19为圈2……,所以,很容易可以得到第n圈有蜂窝6n个(n>0),对于这个等差数列求和,S[1..n]=3n^2+3n,包括第0圈的1,则S[0..n]=3n^2+3n+1。
读入数字x,解方程3n^2+3n+1=x,解出来n=[sqrt(12x-3)-3]/6 如果n为整数,则圈数p=n,否则p=trunc(n)+1,又可以通过公式t:=x-3*sqr(p)+3*p-1;求出t(x是第n圈的第t个)。
可以发现,从上一圈的最后一点,即(p-1,0)走到目的点,首先应在2方向上走1步,再沿(-1,1)走p-1步,其余的5个方向都走p步,此外每走一次,t就要减去相应的值,当t=0时,就可以退出循环,这样就可以很容易得到答案。
#include<stdio.h> #include<math.h> int main(){ double x; int n,t,p,x0,y0,i; while(scanf("%d",&n)!=EOF){ x=(sqrt(12*n-3)-3)/6; p=(int)x; if(3*p*p+3*p+1!=n){ t=n-(3*p*p+3*p+1); p++; x0=p-1; y0=0; while(t){ t--; y0++; for(i=1;i<=p-1&&t;i++,t--)x0--,y0++; for(i=1;i<=p&&t;i++,t--)x0--; for(i=1;i<=p&&t;i++,t--)y0--; for(i=1;i<=p&&t;i++,t--)x0++,y0--; for(i=1;i<=p&&t;i++,t--)x0++; for(i=1;i<=p&&t;i++,t--)y0++; } printf("%d %d\n",x0,y0); } else printf("%d 0\n",p); } return 0; }
下面是另外一种解法,其实都差不多的!!!
#include<iostream> #include<stdio.h> #include<algorithm> #include<iomanip> #include<cmath> #include<cstring> #include<vector> #define ll __int64 #define pi acos(-1.0) #define MAX 50000 using namespace std; struct dir { int x,y; dir(){} dir(int a,int b){ x=a; y=b; } dir operator+(dir A){ return dir(A.x+x,A.y+y); } }an[6],p; int main(){ int i,j,n,k,x,y,m; an[0]=dir(-1,1);an[1]=dir(-1,0);an[2]=dir(0,-1); an[3]=dir(1,-1);an[4]=dir(1,0);an[5]=dir(0,1); while(cin>>n){ k=((sqrt(12.0*n-3.0)-3.0)/6.0); if(3*k*(k+1)+1!=n) k++; p.x=k;p.y=0; m=0; if(k>0) m=6*k-((3*k*(k+1)+1)-n); i=0; while(m){ for(j=0;j<k;j++){ p=p+an[i]; m--; if(m==0) break; } i++; } cout<<p.x<<' '<<p.y<<endl; } return 0; }