16级程序设计基础实践第一次月考
Begin Time: 2016-10-27 13:00:00
End Time: 2016-10-27 14:45:00
Judge: By File
第一次上机考试,题目不难,但是对于初学者来说确实不是很容易AC,毕竟初学者出现错误以后没有办法快速准确地自己看出问题所在。
我做完以后一直等到考试时间结束,期间看着Submitted数字不断地上升,而Accepted数字几乎不动,直到考试结束前半分钟,我记下了这次考试的数据。
A Lab04_01 39.52%(132/334)
B Lab04_02 7.88%(32/406)
C Lab04_03 8.55%(33/386)
D Lab04_04(选做) 25.71%(18/70)
第一题,最简单。
Problem A:Lab04_01
Time Limit:1000MS Memory Limit:30000KB
Description
输入两个整数,第1行输出这两个数的逻辑或的值;第2行输出这两个数的位或的值;第3行输出这两个数的位异或的值。
Input
输入两个整数
Output
第1行输出这两个数的逻辑或的值;第2行输出这两个数的位或的值;第3行输出这两个数的位异或的值。
Sample Input
1 1
Sample Output
1
1
0
直接给出代码,没有需要注意的地方。
#include <stdio.h>
#include <stdlib.h>
int main() {
int a,b;
scanf("%d%d",&a,&b);
printf("%d\n",a||b);
printf("%d\n",a|b);
printf("%d\n",a^b);
return 0;
}
第二题,也不难。
Problem B:Lab04_02
Time Limit:1000MS Memory Limit:30000KB
Description
输入一个非负int类型整数,在一行中输出该数的二进制表示中值为1的位数,以及最简分数表示的占比(格式分子:方母,如1:16,1:1等),位数与占比之间用一个逗号分隔。
例如:
Input:
3
Output:
2,1:16
Note:
示例数据的输出以某个32位的机器为例
Input
输入一个非负int类型整数
Output
在一行中输出该数的二进制表示中值为1的位数,以及最简分数表示的占比(格式分子:方母,如1:16,1:1等),位数与占比之间用一个逗号分隔。
Sample Input
0
Sample Output
0,0:32
这里直接给出代码。
#include <stdio.h>
#include <stdlib.h>
int gcd(int a, int b) {
if (b==0) {
return a;
} else {
return gcd(b,a%b);
}
}
int main() {
unsigned int num;
int i=0,count=0,a[100]= {0};
scanf("%ud",&num);
while (num>0) {
a[i]= num % 2;
num = num / 2;
i++;
}
num=i;
while (i>=0) {
if (a[i]==1) count++;
i--;
}
if (count==0) {
printf("%d,%d:%d\n",0,0,32);
} else {
int div =gcd (count,32);
printf("%d,%d:%d\n",count,count/div,32/div);
}
return 0;
}
需要注意的有这么几点:
1、数组a开到了100,有点浪费了。
2、这里的输入数字num采用的是unsigned int。
3、计数的过程与前一篇略有差异,这里采用的是从数组最后一位往前的方法。
4、由于任何数都是0的因数,所以0与32的最大公约数是32,因此需要单独考虑count为0的情形。
5、约分到最简,就是分子分母同时除以最大公约数。
6、输出结果需要有换行符。
7、变量一定要记得初始化,这里都是赋初值0。
第三题,与上次作业题类似,简单。
Problem C:Lab04_03
Time Limit:1000MS Memory Limit:30000KB
Description
统计并输出一段文字中大写字母开头的单词个数。
例如:
Input:
The C
programming language
Output:
2
Note:
在一行中,单词与单词之间用一个或多个空格分隔,每行末尾有一个换行符
Input
输入一段文本
Output
输出文字中大写字母开头的单词个数
Sample Input
This is a exmaple
there are SOME Books
Sample Output
3
直接给出代码。
#include <stdio.h>
#include <stdlib.h>
int main() {
char ch;
int isnew=1,count=0;
while (scanf("%c",&ch)==1) {
if (ch>='A' && ch <='Z') {
if (isnew) {
count++;
isnew=0;
}
} else {
isnew=0;
if (ch==' '|| ch=='\n'|| ch=='\t') {
isnew=1;
}
}
}
printf("%d\n",count);
return 0;
}
需要注意的有这么几点:
1、因为空格有一个或多个,所以不能单纯地以flag=!flag这种方法来更改逻辑值。
2、判断是否文件结束仍旧采用的是scanf的返回值。
3、
if (ch>='A' && ch <='Z') { //如果这是大写字母
if (isnew) { //判断是不是一个新单词的开头
count++; //如果是,就让计数器加1
isnew=0; //并且把isnew设置为false
}
4、在else的部分,有一句isnew=0。这里详细说说这句话的含义。
题目说的很清楚,“大写字母开头的单词”,也就是说大写字母必须在首位才是计数的,例如Apple是计数的,SOME是仅记一次(而不是四次),heLLo是不计数的。
但是事实上,在OJ判断的时候,似乎只考虑了Apple、apple、APPLE这样的情况,并没有考虑到aPPlE这样的情况,所以这句话不写竟然也被OJ认为是通过的。这句话应该是要写的。
else { //否则(也就是不是大写字母)
isnew=0; //一个字符不是大写字母//不论是小写字母还是其他的//都认为之后遇到的不是一个新单词//把isnew设置为false//即便是空格,也先这样处理,之后再改
if (ch==' '|| ch=='\n'|| ch=='\t') {
isnew=1;
//如果是空格,那么之后遇到的就应该是新一个单词了
}
}
5、输出最后要有换行符。
第四题,选做题,难度确实最大,但是只要知道牛顿二项式定理,直接写就是了,没有难度。
Problem D:Lab04_04(选做)
Time Limit:1000MS Memory Limit:30000KB
Description
使用Newton-Raphson算法求解方程:2χ3-4χ2+3χ-6=0在1.5附近的根(保留3位小数)。在一行中输出根的值。
本题没有输入,也不提供示例输出。
直接输出答案的,一律判为0分。
Note:
参考曲线
(注:图略)
Input
无
Output
在一行中输出根的值(保留三位小数)。
Sample Input
无
Sample Output
不给
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double f(double x) {
return (2*pow(x,3)-4*pow(x,2)+3*x-6);
}
//原函数
double f1(double x) {
return (6*pow(x,2)-8*x+3);
}
//导数
int main() {
double x=1.5;
//从1.5开始试
while (fabs(f(x))>0.00001) {
//精度要求
x=(-(f(x)))/(f1(x))+x;
//N-R定理
}
printf("%0.3f\n",x);
//场宽(域宽)
return 0;
}
//特别注意,绝对值是fabs(),不是abs()
正文完。
然后给出某同学的第二题做法。
先给出代码,然后详细说明。
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int main()
{
int p,i,n,t,x,y,u;
scanf("%d",&p);
i=0;
n=0;
t=1;
while(n<32)
{
if((p&t)==t)
{
i++;
}
else
;
n++;
t=pow(2,n);
}
if(i==0||i==1)
{
y=i;
u=32;
}
else if(i%2!=0)
{
y=i;
u=32;
}
else
{
for(x=2; i>=x;)
{
if(i%x==0)
{
y=i/x;
u=32/x;
}
x=2*x;
}
}
printf("%d,%d:%d\n",i,y,u);
return 0;
}
首先值得肯定的是,在没有学过用递归写最大公约数的情况下,能够针对“32是2的5次幂”来分类约分,是很不容易的。并且分类的方法是对的,也就是说,约分部分的程序是对的。
但是,程序的可读性极差。大括号的对齐习惯不是最主要的原因,主要是因为变量名毫无意义,一堆a、b、c、i、p、u,没有人知道是什么意思。
所以,下面说说一般情况下被广为接受的惯用命名法。初学者应该特别注意变量的命名,绝对不能取没有意义的变量名,并且建议不要把循环变量i用作计数器(除非很清楚自己在做什么),以及写上必要的注释。当然,每个人也都会有自己的偏好习惯,所以这些命名法仅供参考。
<
pre class=”lang:xhtml decode:true”>数组
a[]
arr[]
array[]
data[]
e[]
m[]
mat[]
mtx[]
matrix[]
最终答案的临时存储
ans
answer
平均值
ave
avg
average
普通数值
a
b
计数器
c
cnt
count
counter
tot
total
字符
ch
距离
dist
磁盘
disk
深度优先搜索
dfs
被除数
dividend
除数
divisor
动态规划
dp
编辑
edt
edit
editor
没有明确含义的布尔逻辑值(必要时要加注释)
f
flag
有明确含义的布尔逻辑值
isXXX
并且用1表示something is XXX,用0表示something is not XXX
如:
isnew
isprime
isexist
isopen
isfinished
ismore
没有明确含义的函数(必要时要加注释)
f
fac
fact
fct
func
群组
g
grp
gpe
group
最大公约数
gcd
循环变量
i
ii
j
jj
k
kk
定位符
loc
location
长度
len
length
需要输入获取的数据
m
n
num
最大值
max
最小值
min
管理
mgmt
management
指针
p
pt
lnk
link
快速排序
qs
qsort
q_sort
quicksort
余数
rest
返回值
ret
字符串
s
st
str
累加
sum
临时变量
t
tmp
temp
计时器
t
time
mmt
moment
未知量(常见于函数参数表)
x
y
z
并且,变量一般用小写字母,如ans;常量一般用大写字母,如NUMBER、PI、BEGIN;逻辑真与逻辑假一般用全大写,如TRUE、FALSE。

你写的我们好像。。。你懂得