C语言编程题(50道) 更新中...

189 阅读6分钟

判断年份是否为闰年

闰年

  1. 四年一润百年不润:即如果year能够被4整除,但是不能被100整除,则year是闰年。
  2. 每四百年再一润:如果year能够被400整除,则year是闰年。
#include <stdio.h>

void leapYear(int a)
{
	if ((0 == a % 4 && a % 100 != 0) || (0 == a % 400))
		printf("%d年是闰年!\n", a);
	else
		printf("%d年不是闰年!\n", a);
}

int main(void)
{
	leapYear(2001);
	return 0;
}

解题思路

判断传入的年份 取模 4 是否为 0 并 判断 传入的年份 取模 100 是否不等于0 或者 传入的年份 取模 100 是否 等于 0,就满足了条件就是闰年。其它情况都不是闰年

水仙花数

题目:打印出所有的“水仙花数”,所谓“水仙花数”是指一个三位数,其各位数字立方和等于该数本身。

#include <stdio.h>

int main(void)
{
	int i, j, k, n;
	printf("水仙花数是:");
	for (n = 100; n < 1000; n++)
	{
		i = n / 100; /*计算个位数*/
		j = n / 10 % 10; /*计算十位数*/
		k = n % 10; /*计算百位数*/
		if (i * 100 + j * 10 + k == i * i * i + j * j * j + k * k * k)
		{
			printf("%-5d\t",n);
		}
	}
	return 0;
}

思路分析

利用for’循环控制100-999个数,每个数分解出个位,十位,百位。


下面是通过引入math库调用里面的求平方的函数来得出结果

#include <stdio.h>
#include <math.h>

int main(void)
{
	int i, j, k, n;
	printf("水仙花数是:");
	for (n = 100; n < 1000; n++)
	{
		i = n / 100; /*计算个位数*/
		j = n / 10 % 10; /*计算十位数*/
		k = n % 10; /*计算百位数*/
		if (n == pow(i, 3) + pow(j, 3) + pow(k, 3))
		{
			printf("%-5d\t",n);
		}
	}
	return 0;
}

罗马数字

题目要求

罗马数字包含以下七种字符: I, V, X, LCD 和 M

字符数值
I             1
V             5
X             10
L             50
C             100
D             500
M             1000

例如, 罗马数字 2 写做 II ,即为两个并列的 1 。12 写做 XII ,即为 X + II 。 27 写做  XXVII, 即为 XX + V + II 。

通常情况下,罗马数字中小的数字在大的数字的右边。但也存在特例,例如 4 不写做 IIII,而是 IV。数字 1 在数字 5 的左边,所表示的数等于大数 5 减小数 1 得到的数值 4 。同样地,数字 9 表示为 IX。这个特殊的规则只适用于以下六种情况:

  • I 可以放在 V (5) 和 X (10) 的左边,来表示 4 和 9。
  • X 可以放在 L (50) 和 C (100) 的左边,来表示 40 和 90。
  • C 可以放在 D (500) 和 M (1000) 的左边,来表示 400 和 900。

给定一个罗马数字,将其转换成整数。

示例 1:

输入: s = "III"
输出: 3

示例 2:

输入: s = "IV"
输出: 4

示例 3:

输入: s = "IX"
输出: 9

示例 4:

输入: s = "LVIII"
输出: 58
解释: L = 50, V= 5, III = 3.

示例 5:

输入: s = "MCMXCIV"
输出: 1994
解释: M = 1000, CM = 900, XC = 90, IV = 4.
#include <stdio.h>
// 引入string库函数,一会获取字符串的长度需要用到
#include <string.h>

int isLuouma(char* str)
{
	// 声明一个26长度的数组
	int nums[26];
	// 根据ASCII编码表对照关系可看出 当任何字符 - 'A' 字符后得到 26
	// 英文字母的1 到 26 个 所以这个数组刚好可以存储得下,并在对应的
	// 索引位置进行赋值
	nums['I' - 'A'] = 1;
	nums['V' - 'A'] = 5;
	nums['X' - 'A'] = 10;
	nums['L' - 'A'] = 50;
	nums['C' - 'A'] = 100;
	nums['D' - 'A'] = 500;
	nums['M' - 'A'] = 1000;
	// 获取传入的罗马数字的长度
	int len = strlen(str);
	// 循环变量
	int i = 0;
	// 结果变量
	int ans = 0;
	for (; i < len; i ++)
	{
		// 获取 索引为 i 的 数值
		int value = nums[str[i] - 'A'];
		// 首先判断是否还有下一个字符,也就是i < len - 1满足说明还有
		// 然后判断 当前ans 是否小于 下一个字符, 如果小于说明只有
		// 一种情况就是 IV 那么就需要进行 -1 
		if (i < len - 1 && ans < nums[str[i + 1] - 'A'])
		{
			ans -= value;
		}
		else
		{
			ans += value;
		}
	}
	return ans;
}

int main(void)
{
	char str[] = "IV";
	int res = isLuouma(str);
	printf("结果为:%d\n", res);
	return 0;
}

解题思路

模拟:

通常情况下,罗马数字中小的数字在大的数字的右边,若输入的字符串满足该情况,那么可以将每个字符视作一个单独的值,累加每个字符对应的数值即可。

例如:XXVII可视作X + X + I + I = 10 + 10 + 5 + 1 + 1 = 27

若存在小的数字在大的数字的左边的情况,根据规则需要减去小的数字。对于这种情况,我们也可以将每个字符视作一个单独的值,若一个数字右侧的数字比它大,则将该数字的字符相反。

例如XIV可视作X - I + V = 10 - 1 + 5 = 14

测量体重是否标准

题目要求

开发一款软件,根据公式 (身高 - 108) * 2 = 体重,可以有10斤左右的浮动。来观察测试者体重是否合适。

#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <time.h>
#include <stdlib.h>

void ceshi(int num, char* msg)
{
	// 计算标准体重的公式
 	int nur = (num - 108) * 2;
	// 定义一个变量并初始化,记录用户体重是否标准
	char* s = '\0';
	// 通过公式 (标准体重 - 身高) 是否小于等于10 来得到是否标准
	if (abs(nur - num) <= 10)
	{
		s = "标准";
	}
	else
	{
		s = "不标准";
	}
	// 将nur的值和s的值拼接到msg变量中
	sprintf(msg, "你的体重为:%d ,属于 %s 情况", nur, s);
}

int main(void)
{
	printf("请输入你的身高:");
	int i = 0;
	scanf("%d", &i);
	char msg[100];
	// 传入用户输入的身高 和 消息
	// 注意:消息是引用类型的在函数中修改了msg值就会改变然后输出结果
	ceshi(i, msg);
	printf("%s\n", msg);
	return 0;
}

解题思路

  1. 根据公式 可以得到 标准体重
  2. Math.abs(标准体重 - weight) ≤ 10 说明是 ok 否则不ok

冒泡排序

#include <stdio.h>

void sort(int* arr, int len)
{
	// 定义一个flag来记录是否需要交换
	int flag = 1;
	int i = 0;
	for (; i < len - 1; i++)
	{
		int j = 0;
		for(; j < len - i - 1; j++)
		{
			// 判断 前一个元素 是否大于 后一个元素,满足条件进行交换
			if (*(arr + j) > *(arr + j + 1))
			{
				// 交换过把flag改为0
				flag = 0;
				// 元素交换位置
				int temp = *(arr + j + 1);
				*(arr + j + 1) = *(arr + j);
				*(arr + j) = temp;
			}
		}
		// 1 表示后面没有交换过跳出循环结束程序
		// 0 表示还有元素可被交换将flag状态改为1继续程序
		if (flag)
		{
			break;
		}
		else
		{
			flag = 1;
		}
	}
}

int main(void)
{
	int arr[] = { 1, 2, 4, 5, 3, 7, 6 };
	int len = sizeof(arr) / sizeof(arr[0]);
	sort(arr, len);
	int i = 0;
	for (; i < len; i++)
	{
		printf("%d \n",  * (arr + i));
	}
	return 0;
}

解题思路:

  1. 定义flag记录交换状态
  2. 判断前一个值与后一个值的大小
  3. 更改flag状态为0表示有元素可交换,并进行交换元素位置
  4. 判断flag状态如果没有交换的元素就跳出程序,如果有就将flag改为1继续程序

插入排序