ACM一些可能需要的知识在这里简单介绍一下:
一、 64bit整数问题
在g/g++上是用long long来定义,由于ZJU上的是g/g++,so可以用long long型。但是对于一些VC就要用_int64,因此有时需要注意操作系统和编译器。以下给一个简单的例子
#include<stdio.h> int main(){ long long sum[100002],i; //注意i用long long sum[0]=0; int n; for(i=1;i<=100000;i++) if(i%3==0) sum[i]=sum[i-1]+i*i*i; else sum[i]=sum[i-1]+i; while(scanf("%d",&n)!=EOF){ if(n<0) break; printf("%I64d\n",sum[n]); } return 0; }
二、大数组RE问题
在C/C++中, 对于在函数内定义的变量(包括main()函数), 都是在程序的栈空间内分配的(这个空间相对有限)。如果定义一个内存使用量达到MB级别的数组,一般就会Stack Overflow,RE了。所以遇到大数组的时候建议大家都定义成全局变量。这样就可以在编译的时候就为它们分配好足够的空间。
#include <iostream> #include <iomanip> #include <cstring> using namespace std; int startBus[505], endBus[505], flag[505][505]; int main(int argc, char *argv[]) { int T, numLine, numBus, line; double ratio; cin >> T; while(T--){ memset(flag,0, sizeof(flag)); cin >> numBus >> numLine; for(int i=0; i<numLine; i++){ cin >> startBus[i]; } for(int i=0; i<numLine; i++) cin >> endBus[i]; line = 0; for(int i=0; i<numLine; i++){ if(!flag[startBus[i]][endBus[i]]) line ++; flag[startBus[i]][endBus[i]] = flag[endBus[i]][startBus[i]] = 1; } ratio = (double)line/numBus; cout<<setiosflags(ios::fixed)<<setprecision(3)<<ratio<<endl; } return 0; }
更具体的可以参见luoxi同学的这篇日志。
http://hi.baidu.com/luoxi0209/blog/item/50364c39b1c2622597ddd8b0.html
三、大数组RE问题
尽量使用scanf和printf (它们的格式化输出功能非常好)。如果字符串,尽量用变通的方式,当然也可以用cout。
四、精度问题
对于float/double的比较,通常可能会有舍入误差(比如0.1这个东西在IEEE754标准下永远不可能精确存储)
导致本来应该相等的不相等,所以建议这样:先定义一个常量,比如精度在10^-9这个额度(要根据具体问题判断这个额度!)
#define EPS (1e-9)
然后用这样一个比较函数:
int cmpDouble(double a, double b){
if(fabs(a - b) < EPS) return 0; // a == b
else if(a - b > 0) return 1; // a > b
else return -1; // a < b
}
对于float/double的取整也很有技巧:
floor和ceil不一定能给你你想要的结果(why?)对于一个double类型的a,想想这些表达式的意义:(提示:取(?)整,四舍五入)
(int)(a + EPS)
(int)(a + EPS + 0.5)
以上对于正数成立,对于负数呢?最好还是自己想想
例3:Taxi Fare
#include <iostream> using namespace std; #define epsilon 0.0001 double GetFee(int dis, int t, bool isNew){ double cost; cost = 0; if(isNew){ if(dis < 3) cost += 11; else if(dis < 10) cost += (dis-3)*2.5 + 11; else cost += (dis-10)*3.75 + 2.5*7 + 11; cost += t/4.0*2.5; } else{ cost += 1; if(dis < 3) cost += 10; else if(dis < 10) cost += (dis-3)*2 + 10; else cost += (dis-10)*3 + 2*7 + 10; cost += t/5.0*2; } return cost+epsilon; } int main(){ int T, d, t, oldFee, newFee; cin >> T; while(T--){ cin >> d >> t; newFee = (int)(GetFee(d, t, 1)+0.5); oldFee = (int)(GetFee(d, t,0)+0.5); cout<<newFee - oldFee<<endl; } return 0; }
其它还有一些建议,比如
~ 定义数组的时候开大些
比如题目告诉最多5000个数据,那就开到5010或者更多一些吧