【C语言基础】那些必会的编程练习题-第一部分

简介: 下面我们直接进入正题,希望你在读完题之后可以自己思考并尝试这写一下。

第一题 韩信点兵


题目

相传韩信才智过人,从不直接清点自己军队的人数,只要让士兵先 后以三人一排、五人一排、七人一排地变换队形,而他每次只掠一 眼队伍的排尾就知道总人数了。输入 3 个非负整数 a,b,c ,表示 每种队形排尾的人数(a<3,b<5,c<7),输出总人数的最小值(或 报告无解)。已知总人数不小于 10,不超过 100 。


输入 输入 3 个非负整数 a,b,c ,表示每种队形排尾的人数(a<3,b<5,c<7)。


例 如


输入:2 4


输出 输出总人数的最小值(或报告无解,即输出 No answer)。实例,输出: 89


思路

这道题目通过读题发现我们已知的消息是我们会得到三人,五人,七人一排时队伍排尾的人数,以此求出最小总人数;这道题目考察了我们对取余的掌握程度,也就是我们可以首先利用一个for循环,让数字从10不断向100递增,之后在每一个数时去判断,判断其数字对3,5,7取余的结果与我们已知的排尾数是不是相同的,如果三个都相同的话,我们就直接跳出循环输出即可,如果到99时仍然不行,那么就输出 No answer。


这里我们会用到一个 && ,&&:逻辑与,前后条件同时满足表达式为真。如果a&&b为真的话,那么a和b都应该为真才行。


AC

#include <stdio.h>
int main()
{
  int a ;
  int b ;
  int c ;
  int i ;
  scanf("%d%d%d",&a,&b,&c) ;
  for(i=10;i<=100;i++)  //从10开始递增 
  {
    if(i%3==a && i%5==b && i%7==c)  //判断其是否全部满足队尾数 
    {
      printf("%d\n",i) ;
      break ;   //如果满足,跳出循环 
    }
  }
  if(i==101)    //如果自动循环结束,输出 No answer
    printf("No answer\n") ;
  return 0;
}


第二题 兰州烧饼


题目

烧饼有两面,要做好一个兰州烧饼,要两面都弄热。当然,一次只 能弄一个的话,效率就太低了。有这么一个大平底锅,一次可以同 时放入 k 个兰州烧饼,一分钟能做好一面。而现在有 n 个兰州烧饼, 至少需要多少分钟才能全部做好呢?


输入


依次输入 n 和 k,中间以空格分隔,其中 1 <= k,n <= 100


输出


输出全部做好至少需要的分钟数


提示


如样例,三个兰州烧饼编号 a,b,c,首先 a 和 b,然后 a 和 c,最后 b 和 c, 3 分钟完


思路

这里一个饼子是要煎两次的,所以n个饼子我们要煎2n次;首先我们先判断饼子数量是否比锅容纳数量多,如果没有的话,我们只需花费两分钟去热一下正反面就好了;如果比锅所能容纳数量多的话,我们就用总次数去除以锅每次可以热的个数;但是这里我们得到的结果并不一定时最终答案,因为我们整形相除,最后结果是会将后面小数部分保留的,但是小数部分代表了这次锅并没有装满,但一样要花费一分钟,所以这时我们要判断一下,总次数与锅容量的模了,如果模不为0就直接++即可。


讲一下EOF的用法,我们在使用时通常是这样使用的:while(scanf("%d",&n) != EOF) ;                EOF全称是End Of File(C语言标准函数库中表示文件结束符),通常在文本的最后表示资料结束。C语言中数据都是以字符的ASCII代码值来存放的。ASCII代码值得范围是0~127,不可能出现-1,因此可以用EOF作为文件结束标志。while(scanf("%d",&n) != EOF) 中while(A)语句中的事件A是正确即1,while(1){ },进行下一循环。scanf("%d",&n) != EOF什么时候为1呢?就是我们输入的数组他不等于EOF就可以。也就是说如果n可以正确读取,我们就可以进入下一个循环;当我们不输入n时,循环就终止。


AC

#include <stdio.h>
int main()
{
  int n ;
  int k ;
  int total ;
  int result ;
  while(scanf("%d%d",&n,&k)!=EOF)
  {
    total=n*2;  //一个饼要热两次
    if(n<=k)  //如果锅一次能煎饼的个数比总个数多 
    {         //正面和反面不能同时热 
    printf("2\n");  // 直接花费两分钟去热正面和反面  
    continue;
    }
    //当锅一次能煎饼的个数没有总个数多时
    result=total/k ;  //将次数与一次可热数量直接进行相除 
    if(total%k!=0)  //最后一次热的饼数少于锅所能装整数 
    result++ ;    //由于我们用整型相除,所以末尾没有达到1的会舍去,但这些也要占用时间。 
    printf("%d\n",result);
  }
  return 0;
  }


第三题 进制转换


题目

输入一个十进制数 N,将它转换成 R 进制数输出。


输入


输入数据包含多个测试实例,每个测试实例包含两个整数 N(32 位整数) 和 R((2<=R<=16)。


输出 为每个测试实例输出转换后的数,每个输出占一行。如果 R 大于 10,则 对应的数字规则参考 16 进制(比如,10 用 A 表示,等等)


思路

进制也就是进制位,对于接触过电脑的人来说应该都不陌生,我们常用的进制包括:二进制、八进制、十进制与十六进制,它们之间区别在于数运算时是逢几进一位。比如二进制是逢2进一位,十进制也就是我们常用的0-9是逢10进一位。其他的同理。 好的,接下来就是进制之间的互相转换了。 二进制与十进制之间的转换


其实进制转换的方法大致如下:


1将十进制转换为r进制时,可将此数分为整数和小数两部分分别转换,然后拼接起来即可。


2整数部分转换为r进制数时,采用除r取余方法,即将十进制整数不断除以r取余数,直到商为0,所得的余数按逆序排列


3小数部分转换成r进制数时,采用乘r取整方法,即将十进制小数不断乘以r取整数,直到小数部分为0或达到要求的精度为止,所得的整数按正序排列。


4实际上,在我们的日常生活中,还会遇到很多计数法。如时间:60秒为1分,60分为1小时,它是60进制的。两根筷子为一双,两只手套为一幅,它们是二进制的。


5为了区分不同的进位制,我们有时常在数的右下角标明基数。但是十位制一般不标明基数。一般地,若k是一个大于1的整数。那么以k为基数的k位制可以表示为一串数字连写在一起的形式。


AC

#include <stdio.h>
int main()
{
  int number ;
  int system ;
  char s[50] ;
  int i ;
  int length ;
  int flag ;
  while((scanf("%d%d",&number,&system))!=EOF)
  {
    i=0 ;
    flag=0 ;
  if(number<0)
    {
    number=-number; //负数转化为正数去进行转化 
    flag=1;
  }
  while(number)
  {
    if(number%system<=9)
    {
    s[i]=(number%system)+'0'; //通过进制的原理去按位进行分解 
      }
  else if(number%system==10)  //针对高进制 
    s[i]='A';
  else if(number%system==11)
    s[i]='B';
  else if(number%system==12)
    s[i]='C';
  else if(number%system==13)
    s[i]='D';
  else if(number%system==14)
    s[i]='E';
  else if(number%system==15)
    s[i]='F';
  number/=system ;  //降位数 
  i++ ;
  }
  length=i ;
  if(flag==1)
  printf("-") ;
  for(i=length-1;i>=0;i--)
  printf("%c",s[i]) ;
  printf("\n") ;
  }
  return 0;
  }


第四题 第几天?


题目

给定一个日期,输出这个日期是该年的第几天。


输入


输入数据有多组,每组占一行,数据格式为 YYYY/MM/DD 组成,具体参 见 sample input ,另外,可以向你确保所有的输入数据是合法的。


输出


对于每组输入数据,输出一行,表示该日期是该年的第几天。


思路

对于这道题目我们首先设置一个数组,用下标对应月份,每个月份的天数用数组元素去进行表示,


之后我们传入具体日次后,先将前面月份的天数相加上,之后我们在将当月已过的天数加上即可。


注意:我们在判断的时候要注意闰年的存在,这时2月会变的不一样。


AC

#include <stdio.h>
int main()
{
int a;
int b;
int c;
int i;
int day[13];
int sum;
day[1]=31;
day[2]=28;
day[3]=31;
day[4]=30;
day[5]=31;
day[6]=30;
day[7]=31;
day[8]=31;
day[9]=30;
day[10]=31;
day[11]=30;
day[12]=31;
while((scanf("%d/%d/%d",&a,&b,&c))!=EOF)
{
sum=0;  //总天数 
for(i=1;i<=b-1;i++)
sum+=day[i];  //每个月每个月的叠加 
sum+=c;
if((a%400==0 || (a%4==0 && a%100!=0)) && b>=3)  //判断是否为闰年以及是否使用的上2月 
sum++;
printf("%d\n",sum);
}
return 0;
}


第五题 成绩转换


题目

输入一个百分制的成绩 M,将其转换成对应的等级,具体转换规则 如下:


90~100 为 A; 80~89 为 B; 70~79 为 C; 60~69 为 D; 0~59 为 E;


思路

对于这道题目我们采用if elseif语句去进行判断即可,我们首先从大向小判断,因为如果我们从小到大判断的话,成绩大于八十的可能大于九十,也有可能不大于九十,这样就会出错,但是当我们把成绩大于九十的提前去判断之后,那么剩下大于八十的就不会大于九十了。


AC

#include <stdio.h>
int main()
{
  int T;
  int n;
  char c;
  scanf("%d",&T);
  while(T--)
  {
  scanf("%d",&n);
  if(n>=90) //90 - 100成绩 
  c='A';
  else if(n>=80)  //80-90成绩 
  c='B';
  else if(n>=70)  //70-80成绩 
  c='C';
  else if(n>=60) //60-70成绩 
  c='D';
  else  //60以下成绩 
  c='E';
  printf("%c\n",c);
    }
  return 0;
}

好啦,第一部分的题目就那么多,相信你都会做啦吧,记得及时复习巩固,我们还会接着向下继续学习的。



相关文章
|
1月前
|
NoSQL C语言 索引
十二个C语言新手编程时常犯的错误及解决方式
C语言初学者常遇错误包括语法错误、未初始化变量、数组越界、指针错误、函数声明与定义不匹配、忘记包含头文件、格式化字符串错误、忘记返回值、内存泄漏、逻辑错误、字符串未正确终止及递归无退出条件。解决方法涉及仔细检查代码、初始化变量、确保索引有效、正确使用指针与格式化字符串、包含必要头文件、使用调试工具跟踪逻辑、避免内存泄漏及确保递归有基准情况。利用调试器、编写注释及查阅资料也有助于提高编程效率。避免这些错误可使代码更稳定、高效。
229 12
|
2月前
|
存储 算法 Linux
C语言 多进程编程(一)进程创建
本文详细介绍了Linux系统中的进程管理。首先,文章解释了进程的概念及其特点,强调了进程作为操作系统中独立可调度实体的重要性。文章还深入讲解了Linux下的进程管理,包括如何获取进程ID、进程地址空间、虚拟地址与物理地址的区别,以及进程状态管理和优先级设置等内容。此外,还介绍了常用进程管理命令如`ps`、`top`、`pstree`和`kill`的使用方法。最后,文章讨论了进程的创建、退出和等待机制,并展示了如何通过`fork()`、`exec`家族函数以及`wait()`和`waitpid()`函数来管理和控制进程。此外,还介绍了守护进程的创建方法。
C语言 多进程编程(一)进程创建
|
2月前
|
Linux C语言
C语言 多进程编程(三)信号处理方式和自定义处理函数
本文详细介绍了Linux系统中进程间通信的关键机制——信号。首先解释了信号作为一种异步通知机制的特点及其主要来源,接着列举了常见的信号类型及其定义。文章进一步探讨了信号的处理流程和Linux中处理信号的方式,包括忽略信号、捕捉信号以及执行默认操作。此外,通过具体示例演示了如何创建子进程并通过信号进行控制。最后,讲解了如何通过`signal`函数自定义信号处理函数,并提供了完整的示例代码,展示了父子进程之间通过信号进行通信的过程。
|
2月前
|
Linux C语言
C语言 多进程编程(四)定时器信号和子进程退出信号
本文详细介绍了Linux系统中的定时器信号及其相关函数。首先,文章解释了`SIGALRM`信号的作用及应用场景,包括计时器、超时重试和定时任务等。接着介绍了`alarm()`函数,展示了如何设置定时器以及其局限性。随后探讨了`setitimer()`函数,比较了它与`alarm()`的不同之处,包括定时器类型、精度和支持的定时器数量等方面。最后,文章讲解了子进程退出时如何利用`SIGCHLD`信号,提供了示例代码展示如何处理子进程退出信号,避免僵尸进程问题。
|
2月前
|
消息中间件 Unix Linux
C语言 多进程编程(五)消息队列
本文介绍了Linux系统中多进程通信之消息队列的使用方法。首先通过`ftok()`函数生成消息队列的唯一ID,然后使用`msgget()`创建消息队列,并通过`msgctl()`进行操作,如删除队列。接着,通过`msgsnd()`函数发送消息到消息队列,使用`msgrcv()`函数从队列中接收消息。文章提供了详细的函数原型、参数说明及示例代码,帮助读者理解和应用消息队列进行进程间通信。
|
2月前
|
缓存 Linux C语言
C语言 多进程编程(六)共享内存
本文介绍了Linux系统下的多进程通信机制——共享内存的使用方法。首先详细讲解了如何通过`shmget()`函数创建共享内存,并提供了示例代码。接着介绍了如何利用`shmctl()`函数删除共享内存。随后,文章解释了共享内存映射的概念及其实现方法,包括使用`shmat()`函数进行映射以及使用`shmdt()`函数解除映射,并给出了相应的示例代码。最后,展示了如何在共享内存中读写数据的具体操作流程。
|
2月前
|
消息中间件 Unix Linux
C语言 多进程编程(二)管道
本文详细介绍了Linux下的进程间通信(IPC),重点讨论了管道通信机制。首先,文章概述了进程间通信的基本概念及重要性,并列举了几种常见的IPC方式。接着深入探讨了管道通信,包括无名管道(匿名管道)和有名管道(命名管道)。无名管道主要用于父子进程间的单向通信,有名管道则可用于任意进程间的通信。文中提供了丰富的示例代码,展示了如何使用`pipe()`和`mkfifo()`函数创建管道,并通过实例演示了如何利用管道进行进程间的消息传递。此外,还分析了管道的特点、优缺点以及如何通过`errno`判断管道是否存在,帮助读者更好地理解和应用管道通信技术。
|
2月前
|
存储 Ubuntu Linux
C语言 多线程编程(1) 初识线程和条件变量
本文档详细介绍了多线程的概念、相关命令及线程的操作方法。首先解释了线程的定义及其与进程的关系,接着对比了线程与进程的区别。随后介绍了如何在 Linux 系统中使用 `pidstat`、`top` 和 `ps` 命令查看线程信息。文档还探讨了多进程和多线程模式各自的优缺点及适用场景,并详细讲解了如何使用 POSIX 线程库创建、退出、等待和取消线程。此外,还介绍了线程分离的概念和方法,并提供了多个示例代码帮助理解。最后,深入探讨了线程间的通讯机制、互斥锁和条件变量的使用,通过具体示例展示了如何实现生产者与消费者的同步模型。
|
2月前
|
Linux C语言
C语言 多进程编程(七)信号量
本文档详细介绍了进程间通信中的信号量机制。首先解释了资源竞争、临界资源和临界区的概念,并重点阐述了信号量如何解决这些问题。信号量作为一种协调共享资源访问的机制,包括互斥和同步两方面。文档还详细描述了无名信号量的初始化、等待、释放及销毁等操作,并提供了相应的 C 语言示例代码。此外,还介绍了如何创建信号量集合、初始化信号量以及信号量的操作方法。最后,通过实际示例展示了信号量在进程互斥和同步中的应用,包括如何使用信号量避免资源竞争,并实现了父子进程间的同步输出。附带的 `sem.h` 和 `sem.c` 文件提供了信号量操作的具体实现。
|
3月前
|
传感器 数据采集 API
C语言与硬件编程:GPIO操作
C语言与硬件编程:GPIO操作
143 0