[模拟+二分]zoj 3470:Magic Squares
大致题意:
? ? 如题目中给出的图片
对于这样的一个无线扩展出去的图,输入一个数n,求出数字上下左右的4个数字,按造升序输出。
?
大致思路:
? ? 突破点在,对于每一圈右下角的数字都是(a*2-1)*(a*2-1),a为当前在第a圈。如此,通过二分枚举判定出这个点在第几个圈内。然后在推导这个点和上下左右点的关系。
?
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;long long getround(long long n){long long left=0,mid,right=sqrt(2000000003),res;//1000000003if(n==1)return 1;while(right>=left){mid=(right+left)/2;long long tmp=mid;tmp=tmp*2-1;tmp*=tmp;if(tmp<n){res=mid;left=mid+1;}else{right=mid-1;}}return res+1;}int main(){long long i,j,k,loc,a,s,l,cas,b,c,d,n;cin>>cas;while(cas--){cin>>n;loc=getround(n);if(n==1){printf("2 4 6 8\n");continue;}l=loc*2-1;s=(loc-1)*2-1;s*=s;if(n==s+1){cout<<s<<" "<<n+1<<" "<<(loc*2-1)*(loc*2-1)<<" "<<(loc*2-1)*(loc*2-1)+2<<endl;continue;}if(n>s+1&&n<=s+l-2){a=s-3*(l-3)+1;a-=(s+l-1-n);b=n-1;c=n+1;d=(l-1)*4+1+n;cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;continue;}if(n==s+l-1){a=n-1;b=n+1;c=n+4*l-3;d=c+2;cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;}if(n>s+l-1&&n<s+2*(l-1)){a=n+1-4*(l-2);b=n-1;c=n+1;d=n+4*l-1;cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;continue;}if(n==s+2*(l-1)){a=n-1;b=n+1;c=n+4*l-1;d=n+4*l+1;cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;continue;}if(n>s+2*(l-1)&&n<s+3*(l-1)){a=n-1-4*(l-2);b=n-1;c=n+1;d=n+4*l+1;cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;continue;}if(n==s+3*(l-1)){a=n-1;b=n+1;c=n+4*l+1;d=n+4*l+3;cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;continue;}if(n>s+3*(l-1)&&n<s+4*(l-1)){a=n-3-4*(l-2);b=n-1;c=n+1;d=n+4*l+3;cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;continue;}if(n==s+4*(l-1)){// cout<<"fuck";a=n-3-4*(l-2);b=n-1;c=n+1;d=n+4*l+3;cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;}}return 0;}??