CDOJ1618 SaSet

  题目地址http://acm.uestc.edu.cn/problem.php?pid=1618

  题目分析SaSet定义为平方数的有序集合:{0149...n*n}。在这个集合上定义了5种运算:

    1. a + 0 = a

    2. a - 0 = a

    3. a + 1 :按序排列的平方数中,排在a后面一个的那个;

    4. a - 1:按序排列的平方数中,排在a前面一位的那个;

    5. a + b:这种运算被分解为两个基本运算:(a + 1+b - 1)。

  Input会包含多组ab,计算每组a + b的结果并输出。

  解题思路:既然SaSet是平方数的有序集合,那就用一个数组set[400]来存咯。下标为i的元素就是i*i。所以程序先构造出这个set[400]吧。(有经验的ACMer发现这个数组是可以不用的)

  然后找到a在数组中的位子ib在数组中的位子ji不就是sqrta)么?j不就是sqrtb)么?所以前面说这个数组可以不用有,不过这样做思路会比较清晰)。

  对于四种基本运算自然会想到如下的处理:

    1. a + 0:直接返回a(或迭代结束);

    2. a - 0:直接返回a(或迭代结束);

    3. a + 1:返回set[ i+1 ](或a=set[ i+1 ],结束迭代。当然也可以直接a=i+1^2);

    4. a - 1:返回set[ i-1 ](或a=set[ i-1 ],结束迭代。当然也可以直接a=i-1^2);

    5. a + b:这个递归、迭代均可:

  递归:查询(set[ a+1 ]+set[ b-1 ])并返回查询值;

  迭代:a=set[ i+1 ], b=set[ j-1 ], i++, j--;

  这样总能到达b==1这个状态!然后返回set[ a+1 ],递归结束,或a=set[ a+1 ],迭代结束。

  能有更简单的方法吗?有!

  a + b = sqrta) +  sqrtb))^2// That's all !!!!!!

  源代码

    #include<cstdio>
#include<cmath>
int main()
{
int T,a,b,t;
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&a,&b);
t=(sqrt(a)+sqrt(b))*(sqrt(a)+sqrt(b));
printf("%d\n",t);
}
return 0;
}

 

posted on 2011-12-21 09:12  Lattexiaoyu  阅读(207)  评论(0编辑  收藏  举报

导航