暑假学习打卡【3】——北理工乐学第三周作业

1、分数的四则运算

在小学时我们就学习了分数的四则运算,即对两个分数进行加、减、乘、除等运算,现在我们尝试下用C语言来实现。

输入:

    分数1 操作符 分数2

输出:

    计算结果

要求:

计算结果使用分数表示,并且为最简化。例如结果为2/6,则被简化为1/3

#include <stdio.h>  
int main()  
{  
    int x1, x2, y1, y2, b, c,i;  //b为结果的分子,c为结果的分母
    char a;//a表示加减乘除符号,b表示分子,c表示分母  
    scanf("%d/%d %c %d/%d", &x1, &x2, &a, &y1, &y2);  
  
    switch (a)  
    {  
    case '+':  
        b = x1 * y2 + x2 * y1;  
        c = x2 * y2;  
        break;  
    case '-':  
        b = x1 * y2 - x2 * y1;  
        c = x2 * y2;  
        break;  
    case '*':  
        b = x1 * y1;  
        c = x2 * y2;  
        break;  
    case '/':  
        b = x1 * y2;  
        c = x2 * y1;  
        break;  
    }  
  
 for(i=b;i>=1;i--)  //判断分子分母是否能够化简
 {  
  if((b%i==0)&&(c%i==0))  
  {  
   b=b/i;  
   c=c/i;  
  }  
 }  
    if(b==0)  
    {  
    printf("%d/%d %c %d/%d = 0\n", x1, x2, a, y1, y2);  
    }  
    else if(c==1)  
    {  
        printf("%d/%d %c %d/%d = %d\n", x1, x2, a, y1, y2, b);  
    }  
    else  
    {  
        printf("%d/%d %c %d/%d = %d/%d\n", x1, x2, a, y1, y2, b, c);  
    }  
    return 0;  
}  

小提醒:在switch里面的每个case结束后最好都带个break~

------------------------------------------------这里是无情的切割线------------------------------------------------------

2、【中学】计算时钟的夹角

背景:

钟面上的时针和分针之间的夹角总是在 0 ~180之间 ( 包括 0 和180 ) 。举例来说,在十二点的时候两针之间的夹角为 0 ,而在六点的时候夹角为180 ,在三点的时候为90 。本题要解决的是计算 12:00 到 11:59 之间任意一个时间的夹角。

输入:

每组测试数据包含两个数字:第一个数字代表小时 ( 大于 0 小于等于 12) ,第二个数字代表分 ( 在区间 [0, 59] 上 ) 。

输出:

对应每组测试数据,用常用格式显示时间以及这个时候时针和分针间的最小夹角,精确到小数点后一位。输出格式如下所示。

再看一看,想一想:是否可以不用if 语句,只使用 printf 函数来简化你的程序?

首先是考虑使用if语句的情况:

#include <stdio.h>    
int main()//计算时针与分针的角度   
{  
    int x,y,z;  
    double a,b;//x表示小时数,y表示分钟数,a表示时针转过角度,b表示分针转过角度   
    scanf("%d  %d",&x,&y);  
	if(x<=6)   z=x;    
    else    z=(12-x);  
    a=y*0.5+z*30.0;  
    b=y*6.0;  
    if(a>b)
    printf("At %d:%02d the angle is %.1f degrees.\n", x,y,a-b);
    else
    printf("At %d:%02d the angle is %.1f degrees.\n", x,y,b-a);    
    return 0;  
}  

根据课上所学的,若是想要把if语句省略掉,我自己的想法就是用三目式来替代: 

#include <stdio.h>    
int main()//计算时针与分针的角度   
{  
    int x,y,z;  
    double a,b;//x表示小时数,y表示分钟数,a表示时针转过角度,b表示分针转过角度   
    scanf("%d  %d",&x,&y);  
    z=(x<=6)?x:12-x; 
    a=y*0.5+z*30.0;  
    b=y*6.0;  
    printf("At %d:%02d the angle is %.1f degrees.\n", x,y,(a>b)?a-b:b-a);  
    return 0;  
}  

------------------------------------------------这里是无情的切割线------------------------------------------------------

3、【中学】求解一元二次方程

初中的小明已经开始学习求解一元二次方程了,下面让我们来教计算机如何求解。输入 a,b,c ,求一元二次方程 ax²+bx+c=0 的根。

输入:
假设 a,b,c均int。

输出:
要求输出的根为 double 型,保留 6 位小数。

我先贴一下我第一次做这道题的代码,纯纯就是硬干,但是显然看起来很麻烦: 

#include <stdio.h>  
#include <math.h>  
int main()  
{  
    double a,b,c,delta;//一元二次方程为ax^2+bx+c=0; delta为方程的根 ;    
    scanf("%lf %lf %lf",&a,&b,&c);  
    delta=b*b-4*a*c;  
   

    if(a==0&&b==0)  //当该方程式只有常数项,即形式为c=0时:
    printf("Input error!\n");  


    else if(a==0&&b!=0)  //当该方程式的二次项为零,即形式为bx+c=0时:
    {  
        if(-c/b==0)  
        printf("x=%.6f\n",0);    
        else 
        printf("x=%.6f\n",-c/b);  
    }   
    

    else if(a!=0&&b==0)  //当该方程式的一次项为零,即形式为ax^2+c=0时:
    {  
        if(-c/a>0)  
        printf("x1=%.6f\nx2=%.6f\n",sqrt(-c/a),-sqrt(-c/a));  
        
        else if(-c/a==0)  
        printf("x1=x2=%.6f\n",0);  
        
        else if(-c/a<0)  
        {  
        double x=fabs(-c/a);//x表示c/a的绝对值,方便之后的开根号   
        printf("x1=%.6fi\nx2=%.6fi\n",sqrt(x),-sqrt(x));  
        }  
    }  
   

   else if(a!=0&&b!=0)  //为标准的一元二次方程时:
   {  

    if(delta==0)  
    printf("x1=x2=%.6f\n",(-b)/(2*a));  

    else if(delta>0)  
    {  
        printf("x1=%.6f\n",(-b+sqrt(delta))/(2*a));  
        printf("x2=%.6f\n",(-b-sqrt(delta))/(2*a));  
    }  
    

    else    //当情况属于复数时:
    {  
        double y=fabs(delta);  
        printf("x1=%.6f+%.6fi\n",-b/(2*a), sqrt(y)/(2*a));  
        printf("x2=%.6f%.6fi\n",-b/(2*a), -sqrt(y)/(2*a));  
    }  
   }  
  return 0;
}  

再来做这道题,重新捋一下思路,首先是a=0且b=0时单独讨论,然后根据判别式来开干(

#include <stdio.h>  
#include <math.h>  
int main()  
{  
    double a,b,c,delta;//一元二次方程为ax^2+bx+c=0; delta为方程的根 ;    
    scanf("%lf %lf %lf",&a,&b,&c);  
    delta=b*b-4*a*c;  

    if(a==0&&b==0)  //当该方程式只有常数项,即形式为c=0时:
    printf("Input error!\n");  
    
    else if(a==0&&b!=0)  //当该方程式为一次函数时: 
    {  
        if(-c/b==0)  
        printf("x=%.6f\n",0);   
        else  
        printf("x=%.6f\n",-c/b);  
    }  
    
	else
    {
    	if(delta==0)  //判别式=0时: 
    	{
    		if((-b)/(2*a)==0)
			printf("x1=x2=%.6f\n",0);
			else
			printf("x1=x2=%.6f\n",(-b)/(2*a)); 
		}
    	
		else if(delta>0)  //判别式>0时: 
    	printf("x1=%.6f\nx2=%.6f\n",(-b+sqrt(delta))/(2*a),(-b-sqrt(delta))/(2*a));
    	
    	else    //判别式<0时:    
    	{
    		if(-b/(2*a)==0)
    		{
    		   printf("x1=%.6fi\n", sqrt(fabs(delta))/(2*a));  
               printf("x2=%.6fi\n",-sqrt(fabs(delta))/(2*a)); 
			}
			else
			{
			   printf("x1=%.6f+%.6fi\n",-b/(2*a), sqrt(fabs(delta))/(2*a));  
               printf("x2=%.6f%.6fi\n",-b/(2*a), -sqrt(fabs(delta))/(2*a));
			}  
		}
    }
    return 0;
}  

 

------------------------------------------------这里是无情的切割线------------------------------------------------------

4、【入门】大小写字母转换

我们知道,英文字母是分大小写的,下面我们需要编写一个简单的程序,将输入的全部小写字母变换为大写字母,大写字母变换为小写字母,非写字母保持不变。

输入:

    一个字符

输出:

    变换后的字符

先贴一个最朴实无华的根据ascii码的方法:

#include <stdio.h>
int main()  
{  
    char x;//x表示一个字母   
    scanf("%c",&x);  
    if(x>='A'&&x<='Z')  
    {  
        x+=32;  
        printf("%c\n",x);  
    }  
      
    else if(x>='a'&&x<='z')  
    {  
        x-=32;  
        printf("%c\n",x);  
    }  
      
    else  
    {  
        printf("%c\n",x);  
    }  
    return 0;  
}  

高级一丢丢的可以用:

#include <stdio.h>
#include <ctype.h>
int main()  
{  
    char x;//x表示一个字母   
    scanf("%c",&x);  
    
	if(isalpha(x))  //判断是否为大小写 
	{
		if(islower(x))
		printf("%c\n",toupper(x));   //小写转大写 
		else
		printf("%c\n",tolower(x));   //大写转小写 
	}
	
	else       //原封不动输出 
	printf("%c\n",x);
    return 0;  
}  

------------------------------------------------这里是无情的切割线------------------------------------------------------

5、【日期】根据日期求星期

任意给出一个年月日,求出是星期几。

输入:

    年 月 日

输出:

    0~6。
    星期日用 0 表示,星期一用 1 表示,星期二用 2 表示......星期六用 6 表示。

假设年份大于1900。先想一想:我们现在只会使用 if 语句,该如何建立数学模型?找到数学模型是解决本题的关键。

按照惯例先贴出我第一次做的时候的代码,只能说那时候满脑子都是硬干,加上对C的理解还很浅薄,导致整个代码看起来就很繁琐……

#include <stdio.h>  
int caculate1(int i);  
int main()  
{  
    int year=0, month=0, day=0;//x代表输入年份,y表示输入月份,z表示输入的日份  
    scanf("%d %d %d", &year, &month, &day);  
      
      
    /*解决年的问题*/  
    int i = year - 1;//i表示输入年份的前一年  
    int x = 0;//x表示输入年份的前一年距离1900年1月1日的日子数  
    x=caculate1(i);  
      
      
    /*解决月的问题*/  
    int y = 0;//y表示输入月份的前一月距离本年1月1日的日子数  
    int m;//用于解决2月份是否为闰月的方法  
    if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0)  
    {  
        m = 29;  
    }  
    else {  
        m = 28;  
    }  
    switch (month)  
    {  
    case 1: y = 0;break;  
    case 2: y = 31;break;  
    case 3: y = 31 + m;break;  
    case 4: y = 62 + m;break;  
    case 5: y = 92 + m;break;  
    case 6: y = 123 + m;break;  
    case 7: y = 153 + m;break;  
    case 8: y = 184 + m;break;  
    case 9: y = 215 + m;break;  
    case 10:y = 245 + m;break;  
    case 11:y = 276 + m;break;  
    case 12:y = 306 + m;break;  
    }  
  
    /*解决日的问题*/  
    int z = day;//x表示输入日份距离本月1日的日子数  
  
    int all = x + y + z;//表示总日子数  
    int answer = all % 7;//表示周几  
  
    printf("%d\n", answer);  
    return 0;  
}  
  
  
  
int caculate1(int i)  
{  
    int x1 = 0;//x1表示闰年个数  
    int x2 = 0;//x2表示平年个数  
    int x3 = 0;//x3表示x-1年距离1900年总共的天数  
    if (i < 1900)  
    {  
        x3 = 0;  
        return x3;  
    }  
    else  
    {  
        do  
        {  
            if (i % 4 == 0 && i % 100 != 0)  
            {  
                x1++;  
            }  
            else if (i % 400 == 0)  
            {  
                x1++;  
            }  
            else {  
                x2++;  
            }  
            i--;  
        } while (i >= 1900);  
        x3 = 366 * x1 + 365 * x2;  
        return x3;  
    }  
}  

后面重新做一做这道题,优化一些不必要的步骤:

#include <stdio.h>
int caculate1(int year)  //计算当前年份的前一年的最后一天距离1900.1.1总计多少天数 
{
	int sum=0,i;
	for(i=1900;i<=year-1;i++)
	{
		if((i%4==0&&i%100!=0)||i%400==0)
		sum+=366;
		else
		sum+=365;
	}
	return sum;
}


int main()
{
	int year,month,day,sum,i,j,x;
	scanf("%d %d %d",&year,&month,&day);
	
	sum=caculate1(year);
	int everymonth[12]={31,28,31,30,31,30,31,31,30,31,30,31};//平年的各月份的天数 
	
	if((year%4==0&&year%100!=0)||year%400==0)//闰年修改2月份的天数
	everymonth[1]=29;
	
	for(i=0;i<month-1;i++)   
	sum+=everymonth[i];
	
	sum+=day;
	
	printf("%d\n",sum%7);
}

------------------------------------------------这里是无情的切割线------------------------------------------------------

以上。

  • 5
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
北京理工大学成立于1940年,是中国一所以工科为主、工、理、管、文、法等多学科协调发展的综合性大学。乐学作业是北京理工大学的一种独特教育理念,强调学生在学习过程中的快乐体验和有效成果。 乐学作业的核心理念是让学生从传统的单一教学模式中解放出来,培养积极主动的学习态度和兴趣。同乐学作业也倡导理论与实践相结合,鼓励学生动手实践,锻炼解决问题的能力。 在乐学作业中,学生可以根据自己的兴趣和特长选择适合自己的课程和项目。学校提供了丰富的学科和专业,包括工程、科学、管理、文学、法学等多个领域。学生可以通过多种途径获取知识,例如课堂教学、实验研究、社会实践等。 乐学作业的教学方法也非常灵活多样。老师会根据学生特点和需求提供个性化指导,帮助学生克服学习困难。同,学生在团队合作中也可以相互学习、相互促进。学校还注重培养学生的创新思维和实践能力,鼓励学生进行创新性的研究和项目实践。 乐学作业的目的是培养具备批判性思维、创新意识和实践能力的综合型人才。在这种教育理念下,学生可以更主动地参与学习,享受到学习的乐趣,并且能够更好地适应社会的发展和变化。 作为一所享有盛誉的高校,北京理工大学的乐学作业模式不仅在国内受到关注和推崇,也赢得了国际上的广泛认可。它为学生提供了全面的教育平台,培养了一批才华横溢的年轻人,为社会的进步和发展做出了重要贡献。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值