POJ 2590 Steps

来源:互联网 发布:手机短信的软件 编辑:程序博客网 时间:2024/06/04 20:06

    题目:http://poj.org/problem?id=2590

    题目大意:

    有一条线段,坐标为x,y。然后从x走到y最少的步数是多少,每次走的步的长度有两个限制:

            (1)第一步和最后一步是长度为1。

            (2)当前走的步数的长度比上一步长度多1,或者等于上一步长度,或者比上一步长度少1。

    分析:

   我们发现他们走的步数是有如下规律的:1,2,3,2,1.或者 1,2,2,2,1或者 1,1,1,1,1,1,进一步分析,可以发现

           (1)对于奇数的步数2*n-1,他们最大的走路步数为: 1,2,3,.....n-1,n, n-1........3,2,1。求和为n^2

           (2)对于偶数的步数2*n,他们的最大走路步数为:1,2,3,........n-1,n, n,n-1,.....3,2,1。求和为n^2 + n

    因此,我们可以用二分查找法,找到步数的范围内。只要 (n-1) ^ 2 > y-x > n ^2则需要 2 * n -1步,如果落在 n^2 < y-x < n^2 +n则需要 2 * n.在考虑边界条件。代码如下:

#include<stdio.h>#define  ONLINEvoid online(){#ifdef ONLINE #elsefreopen("2590.in", "r", stdin);freopen("2590.out", "w", stdout);#endif}int cas;unsigned int x, y;int bitserach(unsigned int v){int s = 1;int e = 46340;int mid = 0;if(v == 0)return 0;if (v > e * e + e){return 2 * e + 1;}while (s <= e){mid = (e +s)/2;unsigned int comp0 = mid * mid - mid;unsigned int comp1 = mid * mid;unsigned int comp2 = mid * mid + mid;if (v < comp0){e = mid - 1;}else if (v > comp0 && v <= comp1){return 2 * mid -1;}else if (v > comp1&& v <= comp2 ){return 2 * mid;}elses = mid +1;}}void read(){scanf("%d", &cas);while (cas > 0){scanf( "%d%d", &x, &y);int step = bitserach(y-x);printf("%d\n", step);cas --;}}int main(){online();read();return 0;}
    运行结果如下:

2590Accepted176K0MSC++950B2011-08-03 11:36:24


原创粉丝点击