华工腾讯俱乐部新生练习赛(二 )
比赛地址:http://acm.hdu.edu.cn/webcontest/contest_show.php?cid=772
时间:2011-10-15 19:30-22:00
1001:
练代码能力···
1002:
其实这个东西就是盏···模拟一下三个操作就行···并不难,想清楚了再敲
挺好的一道题···最好不要看网上的解题报告,自己搞出来
1003
小变种费波纳茨···先预处理,求出10^6以内的费波纳茨数,放一个数组里面。
注意这些数会递增的很快,那数组只需要记录每个数模3的结果就行,不然会溢出。
然后每次查询都可以直接用下标输出数组的值。
如果每次都从开始推到输入的n的话,会超时。
另一种方法:
会出现一个长度为8的循环,然后取模一个数就可以了,大家可以推推
1004
可以模拟一下就行。
其实是有公式的:sqrt(n)取整。
引用discuss里面的解释:
就是求一个数的约数个数。若有奇数个约数,开门;偶数个,关门。
设有一数N有有约数B,则必有另一约数N/B,其总是成对出现。惟独完全平方数N=B*B,此是只有一个约数了,完全平方数的约数为奇数个。
设x^2 < n, 就可以得到x = sqrt(n);
1005
最小公倍数。
n, m的最小公倍数 = n*m/gcd(n,m), gcd的意思是最大公倍数。
gcd是经常用到的,大家应该学会,方法就是高中那个“辗转相除"。
这题还有一点要注意,n,m 最大为 10^6, n*m可能达到10^12。
int可以表示的数最大时1^32-1, 大约是2.1*10^8。这里用int就会溢出。
所以我们要用long long / __int64
其实这两个都是一样的,不过有时候由于编译环境,一些OJ或比赛可能只支持其中一个。
他们可以表示的最大整数是1^64-1。
如果用C的输入输出的话,他们的控制符就是%I64d或者%lld,也是因为环境原因,有些地方只支持一个- -
POJ两个都行,ZOJ用lld,HDU用I64d
scanf("%I64d",x);
scanf("%lld",x);
1006
排序。
大家应该学会sort的使用。
#include <algorithm>是头文件。
默认时候,如果对整形数组排序,不需要自定义比较函数。用法:
int a[500];
sort(a, a+100);就是对数组a的前100项升序排序。
如果是vector, 就是:
vector<int> a;
sort(a.begin(), a.end());就是对a整个向量升序排序。
如果有一个结构体
struct point
{
} p[1000];
排序规律:按x降序排,如果x相等,再按y升序排。
这时候我们需要定义比较函数:
int cmp( point aa, point bb )
{
}
其实这东西就是告诉编译器,什么是小于。
sort平均是(nlogn)的复杂度,比冒泡O(n^2)什么的快,这题手写冒泡什么的应该会超时。
具体打大家可以百度一下。
1007:
看起来可能有点恐怖,其实就直接模拟就行。
只有100格,最多100次操作,最坏情况下只要10^4个操作。
一般我们1s可以有10^8个操作。
所以直接模拟。
1008:
DP(动态规划),是acm里面十分重要的一个思想。
这个建议大家先看看百度百科的介绍,慢慢来,一开始可能会觉得很难。
这题,我们定义一个二维数组,dp[110][110],其中dp[i][j]表示在i分钟时候,到达第j棵树的方法数量。
那么就有dp[i][j] = dp[i-1][j-1] + dp[i-1][j+1];
初始化时候,dp[0][p] = 1,其他全部是0, 然后一直推,注意边界的处理。我们可以把dp[x][0]和dp[x][n+1]置0,数组也开大点。
for( i = 1; i <= m; ++i )
最后输出dp[m][t]。
1009:
字符串处理,练代码能力。
1010:
题目长点,没什么好说的 - -