题目地址:http://acm.uestc.edu.cn/problem.php?pid=1618
题目分析:SaSet定义为平方数的有序集合:{0,1,4,9,...,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会包含多组a,b,计算每组a + b的结果并输出。
解题思路:既然SaSet是平方数的有序集合,那就用一个数组set[400]来存咯。下标为i的元素就是i*i。所以程序先构造出这个set[400]吧。(有经验的ACMer发现这个数组是可以不用的)
然后找到a在数组中的位子i,b在数组中的位子j(i不就是sqrt(a)么?j不就是sqrt(b)么?所以前面说这个数组可以不用有,不过这样做思路会比较清晰)。
对于四种基本运算自然会想到如下的处理:
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 = (sqrt(a) + sqrt(b))^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;
}