【练习回顾】第四章 函数与递归

求组合数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的还有一种原因是规则理解的灯下黑。在此题则为对“将军”手段的本能疏忽:使用飞将将军,直接被反杀。
 

posted @ 2021-09-20 09:34  Xlucidator  阅读(28)  评论(0编辑  收藏  举报