Chinaunix首页 | 论坛 | 博客
  • 博客访问: 903118
  • 博文数量: 113
  • 博客积分: 3160
  • 博客等级: 少校
  • 技术积分: 1801
  • 用 户 组: 普通用户
  • 注册时间: 2011-08-19 10:09
文章分类

全部博文(113)

分类: C/C++

2012-06-02 21:50:22

上机直接写代码,时间2小时:

 

 

一张纵横交错的平面网格(围棋棋盘),有N*M个交叉点,每个交叉点都有一个权值 (unsigned int类型),定义:

 

1.连接相邻2个交叉点的线段为边,边的权值是其所连接的交叉点的平均值,共有N*(M- 1)条横边,(N-1)*M条纵边。

 

.4条边围成的区域为格,格的权值是其4个角上的交叉点的平均值,共有(N-1)*(M-1) 个格。

 

 

3.定义一个矩阵变换 N*M to (2N-1)*(2M-1)

 

将输入的N*M个值看做网格上的交叉点的权值,

 

在每个格的中心生成一个新的点,该点权值为其所在格的权值;

 

在每条边的线段中心生成一个新的点,权值为其所在边的权值;

 

这样算上原有的N*M个点,一共有了排列整齐的(2N-1)*(2M-1)个点,将这些点的权值依 

次输出即得到变换后的矩阵。

 

NM都不超过10000,所有权值都用unsigned int表示,在内存中以先行后列的一维数组 

存储,理论值有小数的需要四舍五入。

 

编写程序实现这样一个变换。

 

 

//src为输入,dst作为输出,已指向足够的内存空间

void func(int N, int M, const unsigned int * src, unsigned int * dst);

 

 

基本减分项:

 

1.语法错误 -100

 

2.运行时出错 -90  如果只是对部分测试输入出错,可酌情归入45

 

3.没做完 -80

 

4.题意理解错误 -50

对于没有考虑四舍五入的,可适当轻判。

对于NM用反的,可适当轻判。

 

5.输出结果错误 -40

仅对于部分测试输入,输出错误的,可适当轻判。

如计算两数均值:

c=(a+b+1)/2; //可能溢出

额外减分项:

 

6.不良的代码书写风格 酌情减分

 

7.时间复杂度O(N*M) +10

 

8.遵循先行后列的顺序遍历src +10

 

9.只使用整数类型完成 +10

 

10.用位运算右移代替所有的“/2”、“/4” +10

 

11.循环终止条件写成与0比较 +10

如:for (i = N; i != 0; i--)

 

12.循环中用指针而不是“[]”读写内存 +10

如:*(p+1) //good

p[1] //bad

 

13.常用的简单函数用宏定义 +10

 

如两数求均值,四数求均值等,宏参数加括号的可以再给分。

 

14.访问内存的偏移地址尽量减少重复计算 +10

如:

unsigned int *p;

p = src;

for (i = N; i != 0; i--)

{

……

……

p += M;

}

当然p在第二重循环中能够“++”则更好,可以再加分。

 

 

15.在第一行和第一列处展开循环,而不是在循环中判断 +10

如:

for (i = N; i != 0; i--)

{

if (i == N) //bad!!!

……

else

……

}

好的写法:

……

……

//do i=N

……

for (i = N - 1; i != 0; i--) //start i with N-1

{

//do j=M

……

for (j = M - 1; j != 0; j--) //start j with M-1

{

}

}

 

 

16.能主动对高热度临时变量加register关键字 +10

 

 

额外加分项:

 

 

17.能有意识减少连续指令的依赖性 +20

如:

x = a + b;

x += c;

x += d; //bad

y = e + f;

y += g;

y += h; //bad

好的写法:

x = a + b;

y = e + f; //good,不依赖上一条指令执行结果

x += c + d;

y += g + h; //good,不依赖上一条指令执行结果

能将2组点如此交叉并行计算的可以得满分(+20),否则酌情加分,但不超过10分。

 

 

18.能有意识重复利用运算中间结果 +20

如:

考虑简单的N=2M=3时,6个点

A,B,C

D,E,F.

2个格的权值:

q1=(A+B+D+E)/4, q2=(B+C+E+F)/4

可见其中有重复的运算:(B+E)/4

在编程时,计算q1时保留(B+E)/4这一中间结果,在计算q2时先计算(C+F)/4,再与前面 

中间结果叠加即可得到q2,同时将中间结果更新为(C+F)/4,在M很大时,可以减少大约 

一半的计算量。

 

 

19.写出极高效率的两数求均值代码 +25

 

20.写出极高效率的四数求均值代码 +35

必须与第1718项有机结合才能得满分,否则酌情给分。

 

 

1920项总分超过50分者,若证实是独立原创,不论之前分数,本次测试破格评定为 

A+

阅读(1966) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~