某不知名学校(dgut)C语言作业 这次的作业感觉比上次难一点
而且 这个输入输出是真的恶心 这次老师也没有答案 我只能发自己代码了
这次考的大部分都是数学感觉 语法上的难度不高
第一题
计算函数
按下列要求分别写出两个函数。
(1) 计算n!,计算公式为n!=1×2×3×……×n,函数原型为double fac(int n);
(2) 调用上述函数计算
计算公式如下,函数原型为double cmk(int m, int k);在主函数中调用这两个函数计算 的结果。
分析:求阶乘是一个经典的递归用法 所以这里我也用了递归 当然 用循环也可以写(推荐去尝试一波 感受二者的差别) 不过代码没那么简洁(装13) 重点是函数的实现 假设5的阶乘就是5*4*3*2*1 所以我们依次乘以当前数的n-1就好
在函数里面调用 函数 就是递归 上课应该讲了
个人代码如下(有人跟我反映说这一题输入5 5的时候没有输出 其实你观察一下 m和k是不能相等的 不然分母为0 如果出现了这样的数据 那一定是作业系统逆天了 可以自己加一个if语句判断一下)
# include <stdio.h>
double fac(int n){
if(n==1)return 1;
else return n*fac(n-1);//这里是递归
}
double cmk(int m, int k){
return fac(m)/(fac(k)*fac(m-k));//这里是调用函数
}
int main()
{
int n,m,k;
scanf("%d%d",&m,&k);
printf("%.0lf",cmk(m,k));//保留整数
return 0;
}
输出要整数 我懒得强制转化就直接.0f了 所以说这个作业不过输入输出是真的恶心
第二题
【提高题】找零金额
设人民币的面额有(以元为单位):1分、2分、5分、1角、2角、5角、1元、2元、5元、10元、20元、50元。编写函数void change(double m,double c);其中m为商品价格,c为顾客付款,函数能输出应给顾客找零金额的各种面额人民币的张数,且张数之和为最小。要求在主函数中输入商品价格和顾客付款,调用函数得到结果。
分析:题目说了可以用贪心算法(但是tnnd你让大二过来大二都还没学贪心)贪心是一种基础算法
有兴趣的可以去逝逝,总之我感觉现在才学到函数就让学生用贪心 怕不是要上天
另一个做法是啥 它说了是枚举 也就是用循环一个个遍历一遍 蠢方法 但也确确实实做得出来
个人枚举方法如下:所以面额化成分 然后依次从大到小计数
代码如下
#include<stdio.h>
void change(double m,double c){
double sum=c-m;
int cnt1=0,cnt2=0,cnt3=0,cnt4=0,cnt5=0,cnt6=0,cnt7=0,cnt8=0,cnt9=0,cnt10=0,cnt11=0,cnt12=0;
sum*=100;//转化成 分 为单位
//printf("%lf\n",sum);
while(sum>=5000){
sum=sum-5000;cnt1++;//每个cnt单独计数不同纸币面额
if(sum==0)break;
}
while(sum>=2000){
sum=sum-2000;cnt2++;
if(sum==0)break;
}
while(sum>=1000){
sum=sum-1000;cnt3++;
if(sum==0)break;
}
while(sum>=500){
sum=sum-500;cnt4++;
if(sum==0)break;
}
while(sum>=200){
sum=sum-200;cnt5++;
if(sum==0)break;
}
while(sum>=100){
sum=sum-100;cnt6++;
if(sum==0)break;
}
while(sum>=50){
sum=sum-50;cnt7++;
if(sum==0)break;
}
while(sum>=20){
sum=sum-20;cnt8++;
}
while(sum>=10){
sum=sum-10;cnt9++;
if(sum==0)break;
}
while(sum>=5){
sum=sum-5;cnt10++;
if(sum==0)break;
}
while(sum>=2){
sum=sum-2;cnt11++;
if(sum==0)break;
}
while(sum>=1){
sum=sum-1;cnt12++;
if(sum==0)break;
}
printf("50元:%d\n20元:%d\n10元:%d\n5元:%d\n2元:%d\n1元:%d\n5角:%d\n2角:%d\n1角:%d\n5分:%d\n2分:%d\n1分:%d\n",cnt1,cnt2,cnt3,cnt4,cnt5,cnt6,cnt7,cnt8,cnt9,cnt10,cnt11,cnt12);
}//shi山代码写得想吐 这老师还故意多几种面额给你 然后到时自己再用贪心在学生面前装一下
int main(){
double m,c;
scanf("%lf%lf",&m,&c);
change(m,c);
return 0;
}
跟shi山一样的代码哈哈哈哈 等我11.9补个贪心写法的代码
贪心写法的代码:
#include<stdio.h>
void change(double m,double c){
int i;
int k;
float n;
int cn[20];
float money[]={50,20,10,5,1,0.5,0.2,0.1,0.02,0.01};
int num[10]={0};
k=sizeof(money)/sizeof(float);
n=c-m;
for( i=0;i<k;i++)
{
while(n>=money[i])
{
n=n-money[i];
num[i]++;
}
}
for(i=0;i<k;i++)
{
if(num[i]>0)
printf("%.2f元:%d张 ",money[i],num[i]);
}
printf("\n");
}
int main(){
float m,c;
//printf("请输入商品价格m:");
scanf("%f",&m);
//printf("\n请输入顾客付款金额c:");
scanf("%f",&c);
change(m,c);
}
第三题
回文数
寻找300以内的所有的对称回文数并输出。回文数是指某数与其反序数相等,如5、131、1551、345676543.对称回文数指某数与其平方都是回文数。例如,n=11时,112=121;n=111时,1112=12321。 编写函数int huiwen(long n),判断n是否回文数,如是返回1,否则返回0。 在main函数中遍历300以内的数,寻找对称回文数并输出。
分析:这一题有很多种方法做 比如用/或者%取分割数字 或者用数组存储再倒序 或者直接当作字符翻转 如果是c++更是直接用reverse函数 这里先用一个最简单的方法
下面是个人代码(分割数字实现
#include <stdio.h>
int huiwen(long n) {
int g, k;
g = 0;
k = n;
while (k) {
g = g * 10 + k % 10;//分别取出单个数字 详情见上次作业
k = k / 10;
}
if (g == n)//组合成的数组还跟原来一样 则是回文数
return 1;
else
return 0;
}
int main() {
for (int i = 1; i < 301; i++) {
if (huiwen(i) && huiwen(i * i))//返回1则执行if语句 这是简便写法
printf("%d ", i); //i*i是回文数的平方 也要满足是回文数的条件
}
return 0;
}
第四题
寻找[0,100]区间内所有的孪生素数
寻找[0,100]区间内所有的孪生素数并输出。孪生素数是指差为2的两个素数,例如,3和5,5和7。 编写函数int prime(int n),判断素数。 编写main函数,接收键盘输入的m和n的值,寻找[m,n]区间内所有的孪生素数并输出,并将孪生素数的对数输出,若区间内没有孪生素数,则输出无孪生素数信息。
分析:听起来很复杂 但是实际上也就是要写一个判断素数的函数而已 (只能被1和自己整除)
因此我们我们可以遍历2~n-1 看看有没有它的因数 有则不是素数返回0 没有则是素数返回1
最后在遍历一遍1~100 满足是素数和相隔为2 的条件即可
个人代码如下
#include <stdio.h>
int prime(int n) {
for (int i = 2; i < n ; i++) {
if (n % i == 0)//有因数 返回0
return 0;
}
return 1;//没有 返回1
}
int main() {
for (int i = 0; i <= 98; i++) { //遍历到98就行 因为i+2等于100
if (prime(i) && prime(i + 2))//返回1则执行if语句 这是简便写法
printf("%d,%d\n", i, i + 2);
}
return 0;
}
第五题
哥德巴赫猜想
任何一个大于4的偶数都可以表示为两个素数之和。验证[6,50]之间的偶数 写函数void guest(int n),找到并输出所有素数对,每个素数对之和均等于偶数n。 编写main函数,遍历[6,50]间所有的偶数,调用guest函数查找并输出素数对。 输出格式如下: 40=3+3740=11+2940=17+23(换行)
分析 这题也是看起来复杂 但其实就是要写一个判断素数的函数 跟上一题一样的函数(你也可以用sqrt和n/i来减少遍历时间 不过好像c里面的sqrt函数每次遍历都会被调用 效率还更慢了
另一个难点是输出 要保证字典序输出 就是小数字在大的前面 这里就需要注意自己的循环输出了
个人代码如下:
#include<stdio.h>
#include<math.h> //开方函数头文件
int prime(int m)//该函数判断m是否为素数,如果是则返回1,
{
int i,flag=1;
for(i=2;i<=sqrt(m)&&flag==1;i++)
if(m%i==0)flag=0;
return flag;
}
int main()
{
int m,n;
for(int i=6;i<=50;i+=2){ //题目范围i+=2 保证为偶数
for(m=2;m<50;m++){ //暴力查找素数
for(n=50-m;n>=m;n--){ //注意循环方向
if(prime(m)&&prime(n)&&i==m+n){
printf("%-d=%d+%d ",i,m,n);//-是为了输出对齐 可能系统会卡你输出
}
}
}printf("\n");//每行回车 注意回车位置
}
return 0;
}
第六题
计算吃货协会来了几个新人
学校里的“吃货协会”准备搞一个聚会,已经知道现有会员N人,把会员从1到N编号,其中会长的号码是N号,凡是和会长是老朋友的,那么该会员的号码肯定和N有大于1的公约数,否则都是新朋友,现在会长想知道究竟有几个新朋友?请你编程序帮会长计算出来(N用键盘输入)。 编写函数int gcd(int a,int b),求a和b的最大公约数。 编写main函数,接收键盘输入的N的值,寻找[1,N-1]区间内的与N的最大公约数为1的数字,输出个数。
分析:本题意图很简单 就是要写一个判断公约数的函数 关于判断的方法—辗转相除法(欧几里得算法)已经在上一次作业写过了 这里就不过多赘述
个人代码如下
# include <stdio.h>
int gcd(int a,int b){
int r=a%b; //辗转相除
while(r!=0){
r=a%b;
a = b;
b = r;
r = a%b;
}
return b;/返回最后一个除数
}
int main()
{
int n;
int cnt=0;//计数器
scanf("%d",&n);
for(int i=1;i<n;i++){
if(gcd(n,i)==1){ //如果为1 则是新朋友
cnt++;//一个新朋友就+1
}
}
printf("%d",cnt);
return 0;
}
第七题
用函数输出字符
输出以下结果,用函数调用实现 ****************** How do you do! *****************
分析:越往后面题目越简单 但老师偏偏搞个闯关模式必须先做前面的题 恶心一下同学们
其实这输出要换行 题目也不说
个人代码如下:
# include <stdio.h>
void print(){
printf("******************\n How do you do!\n******************");
}
int main()
{
print();
return 0;
}
第八题
用函数求两数之和
输入两个实数,用一个函数求出它们之和,保留两位小数
分析:后面几题都很水 感觉没什么好分析的了 看看代码就明白了 同时写的时候注意一下数据类型就好
个人代码如下:
# include <stdio.h>
double add(double a,double b){
return a+b;
}
int main()
{
double a,b;
scanf("%lf %lf",&a,&b);
printf("%.2lf",add(a,b));
return 0;
}
第九题
编写函数计算圆柱体体积
编写自定义函数 volume_cy,功能是求圆柱体的体积(v=3.14*r2*h),要求圆柱体的高 h 和底半径 r 在主函数中输入,圆柱体的体积在主函数中做输出。h,r 均为 float型变量。
分析:水题 注意一定要用float就行
个人代码如下:
# include <stdio.h>
#define pi 3.14
float volume_cy(float h,float r){
return pi*r*r*h;
}
int main()
{
float h,r;
scanf("%f %f",&r,&h);
printf("%f",volume_cy(h,r));
return 0;
}
第十题
编写函数求梯形面积
定义函数 areaT,功能是求梯形面积。要求在主函数中输入上底(用变量 a存储)、下底(用变量 b 存储)、和高(用变量 h 存储),在主函数中调用函数 areaT,输出梯形面积(用变量 s 存储)的值。其中,变量 a,b,h,s 数据类型均为 double。公式:s=(a+b)*h/2
分析:水题 看代码
# include <stdio.h>
double areaT(double a,double b,double h){
return (a+b)*h/2.0;//注意加括号
}
int main()
{
double a,b,h;
scanf("%lf %lf %lf",&a,&b,&h);
//areaT(a,b,h);
printf("%.2lf",areaT(a,b,h));
return 0;
}
感觉对你有帮助的话 动动小手点个赞呗~
作业做完了 耶耶耶!