【练习回顾】第四章 函数与递归
求组合数C(n,m)
由于公式特性 \(C_{n}^{m}=\frac{n!}{(n-m)!\cdot m!}\) 妨在求解时,取m和n-m中较大者进行计算
if(m,n-m) m=n-m;
for(int i=m+1;i<=n;++i) ans*=i;
for(int i=1;i<=n-m;++i) ans/=i;
还可以一边乘一边除,扩大上限
关于数据范围
int32: \(46340^2 < 2147483647 < 46341^2\)
gdb调试程序使用
> gcc xx.c -g ------ 生成调试信息
> gdb a.exe
> (gdb) l -----------查看源代码
> (gdb) b n --------在第n行设置断点
> (gdb) r -----------运行程序
> (gdb) s -----------单步执行
> (gdb) bt ----------查看调用栈
> (gdb) up ---------选择上一栈帧
> (gdb) p x---------打印x变量值
段错误(SIGSEGV,Segmentation fault)
Win可执行文件采用PE格式,分为正文段(Text Segment)存储指令;数据段(Data Segment)村塾已初始化的全局变量;BSS段(BSS Segment)存储未赋值的全局变量所需空间。命令size a.exe
查看各段大小
调用栈不存储在可执行文件中。在运行时动态创建在堆栈段(Stack Segment)上,有大小限制,若越界访问,出现段错误,如:栈溢出。
Windows中,栈的大小存储在可执行文件中,可以在编译时控制,例如-Wl,--stack=16777216
将栈大小设为16MB
E4-4 Message Decoding UVa213
1.相同值不同位数的二进制数存储发:二维数组code[8][127]
2.跨行读取:其实只需忽略'\n'
('\r'
)就行。有些小惊喜,自顶向下写完main函数,发掘自己readNit()
还简洁且泛用性不错。
//主干
while(fgets(header,500,stdin)!=NULL){
encodeData(header);
int len=0,tmp;
while( (len=readNbit(3))!=0 ){
while( (tmp=readNbit(len))!=(1<<len)-1 ){
putchar(code[len][tmp]);
}
}
scanf("%*c");
/* 跳出后,缓冲区还剩下一个'\n',若不去除,后续header将只读入'\n' */
puts("");
}
E4-5 Spreadsheet Tracking UVa512
1.在表格位置(i,j)不断变换时,同时保有'当前位置'和'原位置'的信息:初始化时d[i][j]=i*BIG+j
用数组值囊括原位置行列信息(二者正交)
取出信息:d[i][j]/BIG
,d[i][j]%BIG
反转存储:d[d[i][j]/BIG][d[i][j]%BIG]=i*BIG+j
2.这类操作模拟题:由于很多模拟操作对输出结果来说是鸡肋,不妨只关注输出对象在操作下的变化。
注意浮点误差-使用EPS
浮点误差可能会带来肉眼可观的较大差异!当使用EPS时,一般将EPS取值为比最低精度小上几个数量级的数:保留3位小数 -> EPS=1e-6
4-1 Xiangqi UVa1589
1.有现实背景的模拟题,WA的还有一种原因是规则理解的灯下黑。在此题则为对“将军”手段的本能疏忽:使用飞将将军,直接被反杀。