5. (6')代码填空
对一个方阵转置,就是把原来的行号变列号,原来的列号变行号
例如,如下的方阵:
1 2 3 4
5 6 7 8
9 10 11 12
13 14 15 16
转置后变为:
1 5 9 13
2 6 1014
3 7 1115
4 8 1216
但,如果是对该方阵顺时针旋转(不是转置),却是如下结果:
13 9 5 1
14 10 6 2
15 11 7 3
16 12 8 4
下面的代码实现的功能就是要把一个方阵顺时针旋转。
填空后代码:
#include <stdio.h>#include <stdlib.h>void rotate(int* x, int rank){ int* y = (int*)malloc(rank*sizeof(x)); // 填空 int i; for(int i=0; i<rank * rank; i++) { y[rank -1 - i/rank + rank * (i%rank)] = x[i]; // 填空 } for(i=0; i<rank*rank; i++) { x[i] = y[i]; } free(y);}int main(int argc, char* argv[]){ int x[4][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12},{13,14,15,16}}; int rank = 4; rotate(&x[0][0], rank); for(int i=0; i<rank; i++) { for(int j=0; j<rank; j++) { PRintf("%4d", x[i][j]); } printf("/n"); } return 0;}程序截图:
6. (9')代码填空
对于32位字长的机器,大约超过20亿,用int类型就无法表示了,我们可以选择int64类型,但无论怎样扩展,固定的整数类型总是有表达的极限!如果对超级大整数进行精确运算呢?一个简单的办法是:仅仅使用现有类型,但是把大整数的运算化解为若干小整数的运算,即所谓:“分块法”。
如图【1.jpg】表示了分块乘法的原理。可以把大数分成多段(此处为2段)小数,然后用小数的多次运算组合表示一个大数。可以根据int的承载能力规定小块的大小,比如要把int分成2段,则小块可取10000为上限值。注意,小块在进行纵向累加后,需要进行进位校正。
以下代码示意了分块乘法的原理(乘数、被乘数都分为2段)。
填空后代码:
#include <stdio.h>void bigmul(int x, int y, int r[]){ int base = 10000; int x2 = x / base; int x1 = x % base; int y2 = y / base; int y1 = y % base; int n1 = x1 * y1; int n2 = x1 * y2; int n3 = x2 * y1; int n4 = x2 * y2; r[3] = n1 % base; r[2] = n1 / base + n2 % base + n3 % base; r[1] = n2 / base + n3 / base + n4 % base; // 填空 r[0] = n4 / base; r[1] += r[2] / base; // 填空 r[2] = r[2] % base; r[0] += r[1] / base; r[1] = r[1] % base;}int main(int argc, char* argv[]){ int x[] = {0,0,0,0}; bigmul(87654321, 12345678, x); printf("%d%d%d%d/n", x[0],x[1],x[2],x[3]); return 0;}程序截图:
7. (13')代码填空
今有 6 x 6 的棋盘格。其中某些格子已经预先放好了棋子。现在要再放上去一些,使得:每行每列都正好有3颗棋子。我们希望推算出所有可能的放法。下面的代码就实现了这个功能。
初始数组中,“1”表示放有棋子,“0”表示空白。
填空后代码:
#include <stdio.h>int N = 0;bool CheckStoneNum(int x[][6]){ for(int k=0; k<6; k++) { int NumRow = 0; int NumCol = 0; for(int i=0; i<6; i++) { if(x[k][i]) NumRow++; if(x[i][k]) NumCol++; } if(NumRow!=3 || NumCol!=3) return false; // 填空 } return true;}int GetRowStoneNum(int x[][6], int r){ int sum = 0; for(int i=0; i<6; i++) if(x[r][i]) sum++; return sum;}int GetColStoneNum(int x[][6], int c){ int sum = 0; for(int i=0; i<6; i++) if(x[i][c]) sum++; return sum;}void show(int x[][6]){ for(int i=0; i<6; i++) { for(int j=0; j<6; j++) printf("%2d", x[i][j]); printf("/n"); } printf("/n");}void f(int x[][6], int r, int c);void GoNext(int x[][6], int r, int c){ if(c<6) f(x, r, c+1); // 填空 else f(x, r+1, 0);}void f(int x[][6], int r, int c){ if(r==6) { if(CheckStoneNum(x)) { N++; show(x); } return; } if(x[r][c]) // 已经放有了棋子 { GoNext(x,r,c); return; } int rr = GetRowStoneNum(x,r); int cc = GetColStoneNum(x,c); if(cc>=3) // 本列已满 GoNext(x,r,c); else if(rr>=3) // 本行已满 f(x, r+1, 0); else { x[r][c] = 1; GoNext(x,r,c); x[r][c] = 0; if(!(3-rr >= 6-c || 3-cc >= 6-r)) // 本行或本列严重缺子,则本格不能空着! GoNext(x,r,c); }}int main(int argc, char* argv[]){ int x[6][6] = { {1,0,0,0,0,0}, {0,0,1,0,1,0}, {0,0,1,1,0,1}, {0,1,0,0,1,0}, {0,0,0,1,0,0}, {1,0,1,0,0,1} }; f(x, 0, 0); printf("%d/n", N); return 0;}程序截图:
新闻热点
疑难解答
图片精选