[数学] uva 12954 Spiral

来源:互联网 发布:可非止咳糖浆淘宝交易 编辑:程序博客网 时间:2024/05/21 15:50

题目链接:

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4833

----------------------------------------------------------------------------分割线------------------------------------------------------------------------

题意简单明了。就是按照回形蛇数填充n*n的矩阵,给你一个数K,问K的位置在第几行第几列。

----------------------------------------------------------------------------分割线------------------------------------------------------------------------

表示数学不行,我只能把找位置分成几个部分:走完一圈的,走完一条线的,走不完一条线的。

1.对于走完一圈的。我们可以轻易得到第k圈的大小为4*(n-k*2)-4; 然后在写题过程中,我是从第0圈开始的。然后各种艰难。但是目前没尝试从第1圈开始搞。这份题解也是把第0圈当成第1圈写的。

2.对于走一条线的。假设我们现在是在第k圈,那么我们可以得到一条线的长度为n-2*k,n-2*k-1,n-2*k-1,n2*k-2对于最后一个,我们不考虑。因为我们是通过第一步得到它一定在某个圈内。然后我们走了前面三个,如果没有走到的话,一定在第四个里面。

3.其实就是最后面额外处理就好了。

---------------------------------------------------------------------------分割线-------------------------------------------------------------------------

再详细补充坑点:

1.对于第一个。我第一圈是0的说我的式子是:4*(n-2*k)-4;

2.对于第二个要求,我们需要得到它位于第几圈,所以我们需要求这个。

1).通过等差数列求和。假设它完整的走完了k圈,我们可以得到sum=4*(k-1)*(n-k-1)<=K,要求k的最大值

2).通过上面的式子,我们知道sum是一个关于k的一元二次函数,并且开口是向下的,根据题意,sum应该是要越来越大,所以只能拿递增的部分。

3).如何解那个方程?表示懒得想,所以我用了二分去搞,由于只能取递增的部分,所以记得二分的上界不能大于极大值点,也就是(n-2)/2;

4).解完方程就解决了?不不不,还有一个问题,假设没走完一圈的话,结果其实也是0,因为下界是0。

那么得到0的情况下,就不一定走完第0圈了,所以我们分个类讨论下。

5).解决了0圈之后,那么接下来就是预想的走完了k圈了。那么接下来就是模拟走线了。最简单的4个if解决,或者想办法写成循环什么的。

写到这里应该都总结完了。

---------------------------------------------------------------------分割线---------------------------------------------------------------------------

贴代码:

#include<cstdio>#include<cstring>#include<algorithm>int dx[]= {0,1,0,-1};int dy[]= {1,0,-1,0};long long f(long long n,long long mid){return 4*(mid+1)*(n-mid-1);}int main(){long long n,k;while(scanf("%lld%lld",&n,&k)!=EOF) {if(n==1) {printf("%lld %lld\n",1,1);continue;}long long l=0,r=(n-2)/2;long long mid=l+r>>1;while(l<r) {mid=(l+r+1)>>1;long long an=f(n,mid);if(an<=k) {l=mid;} elser=mid-1;}long long now;long long nx,ny;if(f(n,0)>=k) {now=n;nx=1;ny=0;} else {now=n-l*2-2;k-=f(n,l);long long quan=l+1;ny=quan,nx=ny+1;}int i=0;if(k<=now) {nx+=dx[i]*k;ny+=dy[i]*k;printf("%lld %lld\n",nx,ny);continue;} else {k-=now;nx+=dx[i]*now;ny+=dy[i]*now;now--;i++;}for(; i<3&&k>=now; i++) {k-=now;nx+=dx[i]*now;ny+=dy[i]*now;}nx+=dx[i]*k;ny+=dy[i]*k;printf("%lld %lld\n",nx,ny);}return 0;}


0 0
原创粉丝点击