第一题:http://acm.hdu.edu.cn/showproblem.php?pid=2040
时间减少平方级。求一个数的约数只需要枚举到,sqrt(a) 就可以了,不要小看这一个开平方。相当于时间复杂度从O(n^2) 到O(n)
int yueshu(int x) //求x的约数和
{
int ans = 1;
for(int i = 2; i < sqrt(x+1); i++)
{
if(x%i == 0)
{
if(i == x/i)
{
ans += i;
} else
{
ans += (i + x/i);
}
}
}
return ans;
}
第二题:http://acm.hdu.edu.cn/showproblem.php?pid=2041
打表的方式。当答案是可以在询问之前就可以确定的话,是可以考虑有打表的方式将答案先保存起来,也就是先预处理一下,然后对于后面的查询就会变的容易一些,不同的就是对于每一个题来说,求解的方法是不一样的,需要去思考应该怎么去预处理。
这个就是题目的难点,一般而言,是可以先采用最简单的办法去打印一部分数据,然后去找规律。或者是自己去一步一步的用数学去推理,这样也是可以得到解的。
a[1] = 0; a[2] = 1; a[3] = 2; // 数组a[i] 就是保存的台阶i,所需要的次数
for(int i = 4; i <= 40; i++)
a[i] = a[i-1] + a[i-2];
第三题:http://acm.hdu.edu.cn/showproblem.php?pid=2042
和第二题思想一样
long long int ans[31] = {3,4}; // 这里需要用long long 因为这种递推的方式是很容易超出int的范围
for(int i = 2; i < 31; i++)
ans[i] = 2 * ans[i-1] - 2;
第四题:http://acm.hdu.edu.cn/showproblem.php?pid=2045
和第三题思想一样
a[1] = 3; a[2] = 6; a[3] = 6;
for(int i = 4; i<=50; i++)
a[i] = 2*a[i-2] +a[i-1];
第五题:http://acm.hdu.edu.cn/showproblem.php?pid=2048
和第四题思想一样,但是这个题相对而言不太容易找到规律。题目需要求一个概率,每次抽签抽的都不是自己的概率。就是求抽中的人没有一个是自己的排列数a[i]除以所有抽球可能的排列s[i]。当有N个人可以抽出没有一个人是自己的可能a[n]后,再添加一个人(n+1个人),和其中任意一个人交换位置都是可以的,结果为n*(a[n]),同时和其中有且只有一个人抽中了自己的人交换位置也是可以的,那就是n*(a[n-1]) ,为什么是n*(a[n-1])呢。 只有一个人抽中了自己,也就是前面有n-1个人是没有抽到自己的,也就是a[n-1]; 所以递推式就是a[n+1] = n*a[n] + n*a[n-1] = n(a[n]+a[n-1]) 换一下a[n] = (n-1)*(a[n-1] + a[n-2]);
a[1] = 0 ; a[2] = 1;
for(i = 3; i <= 20; i++)
a[i] = (i-1)*(a[i-1] + a[i-2]);
sum[1] = 1;
for(i = 2; i <= 20; i++)
sums[i] = sum[i-1] * i;
/// 最后答案就是 a[n]/sum[n]*100.0
第六题:http://acm.hdu.edu.cn/showproblem.php?pid=2049
和第五题思想一样。有n对夫妻结婚,有m个新郎跪搓衣板。也就是n-m个新郎可以回去洞房。和上面个方法一样.答案就是
m个找错了的a[m],乘以 n个当中选出m
a[m] * sum[n] / sum[n-m] / sum[m]
第七题:http://acm.hdu.edu.cn/showproblem.php?pid=2052
就是一个printf(); 的题。注意控制格式,建议这类题目,先自己在纸上好好的理一下注意事项,容易出错的在于if ...else 没有烤炉到所有情况,或者是考虑了多余的情况。需要仔细的注意。