2022级信息工程学院《C语言程序设计》阶段1考试
Problem A: 七进制转换
Solution
要认真读题的题
- 正经讲过无数次的进制转换,不断取mod做除法
- 判断素数,\(2\) ~ \(\sqrt {n}\)有能除尽的是合数,否则是质数
- 注意审题,“在此将\(1\)视作素数”,瞪眼一个小时看到这句话,我想给出题人两个大逼斗
code
int Sum_Septenary(int n){
int ans = 0, a[105], i = 0, tmp = 0;
while(n != 0){
tmp = n % 7;
n = n / 7;
a[++i] = tmp;
}
int b = 0;
for(b = 1; b <= i; b++)
ans += a[b];
return ans;
}
int Is_Prime(int n){
int lim = sqrt(n), i = 1;
if(n == 1) return 1;
if(n == 2) return 1;
for(i = 2; i <= lim; i++)
if(n % i == 0) return 0;
return 1;
}
Problem B: 字符循环加密
Solution
签到题
平常练习的原题吧,再说题目中给了提示信息,直接翻译就行
可以通过将字母的ASCII值加偏移量后与26求余运算实现该操作
Code
char Encryption(char ch, int k){
if(ch >= 'a' && ch <= 'z'){
return ch = ((int)ch - 'a' + k) % 26 + 'a';
}
else if(ch >= 'A' && ch <= 'Z')
return ch = ((int)ch - 'A' + k) % 26 + 'A';
else return ch;
}
Problem C: X图案打印
Solution
代码实现题
T2可以作为这个题的引子吧,我们考虑每一行应该输出的字母,再考虑每一行的哪个位置输出这个字母
- 经过观察,“边长为\(n\)”指的是中心字母所在位置是第\(n\)行,总共有\(2n-1\)行
- 若在第\(n\)行之上距离为\(k\)行,则字母为中心字母\(ch-k\)
- 若在第\(n\)行之下距离为\(k\)行,则字母为中心字母\(ch+k\)
- 考虑输出位置,对角线吧,坐标符合什么规律就在对角线了呢?
- \(i == j\)
- \(i + j == 2n\)
- 以上——代码实现
#include <stdio.h>
#include <string.h>
char s[5];
char a[30][30];
int abs(int n){
return n > 0 ? n : -n;
}
signed main(){
gets(s);
int len = strlen(s);
int n = 0;
if(s[0] >= '0' && s[0] <= '9' && s[1] >= '0' && s[1] <= '9') n = 10 * (s[0] - '0') + s[1] - '0';
else n = s[0] - '0';
char c = s[len - 1];
if(n > 13 || n <= 0 || c < 'A' || c > 'z') return puts("Input Data Error."), 0;
int i = 0, j = 0;
for(i = 1; i <= n * 2 - 1; i++){
char t;
if(i < n) t = c - (n - i);
else if(i == n) t = c;
else t = c + (i - n);
if(t < 'A') t += 26;
if(t > 'Z') t -= 26;
for(j = 1; j <= n * 2 - 1; j++){
if(i == j || i + j == n + n) printf("%c", t);
else printf(" ");
}
puts("");
}
return 0;
}
Problem D: 商品促销折价
Solution
代码实现细节题
- 第一点,emm题目大意完全照着写个函数即可,制表符'\t',没办法记得就能过,记不得就别过。
- 第二点,输入处理,\(EOF\)形式我们在这里介绍两种,两种等价
while(scanf("") != EOF)
while(~scanf(""))
- '\n'结束时候,建议用\(getchar()\)处理,\(scanf()\)不能读入'\n'
#include <stdio.h>
#include <stdlib.h>
float calPrice(float price){
float ans;
if(price > 200.00) ans = price * 0.92;
else if(price >= 100.00 && price <= 200.00) ans = price * 0.95;
else ans = price;
return ans;
}
signed main(){
float price;
while(scanf("%f", &price) != EOF){
char ch = getchar();
printf("%.2lf", price);
printf("\t\t");
printf("%.2lf\n", calPrice(price));
if(ch == '\n') return 0;
}
return 0;
}
Problem E: 最小二乘法求解线性回归模型
审题、代码实习题
Solution
没有太多技巧,看着变量公式写代码,按照顺序先后求出各种变量的值,得出\(w,b\)后判断绝对值。
void input(double dv[], int n){
int i = 0;
for(i = 1; i <= n; i++) scanf("%lf", &dv[i]);
}
void LeastSquare(double x[], double y[], int num, double *w, double *b){
double sum = 0, x_ave = 0;
int i = 1;
for(i = 1; i <= num; i++) sum += x[i];
x_ave = sum / num;
double w_up = 0.0, w_down = 0.0;
for(i = 1; i <= num; i++)
w_up += y[i] * (x[i] - x_ave);
for(i = 1; i <= num; i++)
w_down += (x[i] * x[i]);
w_down -= num * x_ave * x_ave;
*w = w_up / w_down;
sum = 0.0;
for(i = 1; i <= num; i++)
sum += y[i] - *w * x[i];
*b = sum / num;
if((*w > 0.0 && *w - 0.0 < 1e-3) || (*w < 0.0 && 0.0 - *w < 1e-3)) *w = 0.0;
if((*b > 0.0 && *b - 0.0 < 1e-3) || (*b < 0.0 && 0.0 - *b < 1e-3)) *b = 0.0;
}
总结
- 这次考试题比去年的略难,但是重点考察都在语法上,并没有太多的思维题、算法题,总之考察偏向基础知识和基本语句的运用。
- 除了知识方面,考察的还有大家在考场上应试的心态,崩一道题可能就没心思往下做了。要学会调整心态,一般考试的\(T1、T2\)都会给出一个签到题,一道没看懂或者脑子没转过来都是情有可原的,就往下一题看,回头再来处理可能就是题目一句话(比如1是质数)的事情。
- 基本语法要熟悉,避免低级错误,上考场之前想想自己经常犯得小错误,平时可以通过小本、记事本、便签、备忘录、博客等记录一下,在学习语法的前几个月,尤其是入门阶段尤为重要。在这里列举几个,大家经常犯的以及我在这次考试中犯的错误。
- 变量初始化: 在主函数里面任意位置定义的变量都需要初始化,否则系统会随机给一个内存地址上去,你根本不知道会崩出什么奇奇怪怪的数字。我的建议是,能定义在函数之外的函数统统定义在外面,默认初始化全是空或者为\(0\).
- 循环语句: \(for\)循环里面不可定义任何变量\((C89)\)。\(while\)循环括号里面是能够执行操作的条件。
- \(i++\) 和 \(++i\): 搞不明白就写个循环输出看一下。
- 一些个函数默认使用方式: 比如\(T5\)的取绝对值函数,我们常用的\(abs\)不可用,因为参数要求必须是\(int\)类型;再比如\(pow\)函数求平方,参数要求必须是\(double\)类型。
- 数据类型判断以及使用: 注意\(int\)和\(long long\)
- ……(大家互相交流一下)
- 最后,希望大家以期中为垫脚石,在接下来的学习中接续奋斗,在期末考试中勇夺佳绩!
风吹过,我来过~