C与C++程序设计学习笔记

记录大一学习C语言和C++时的课堂作业

文章目录

一、循环结构程序设计
二、数组
三、自定义函数
四、指针
五、结构体
六、数据读取和数据存储
七、基础算法题


一、循环结构程序设计

1、求s=1+2+3+……+98+99+100的值。
#include <stdio.h>
int main(void)
{
	int s = 0, i = 0;
	for (i = 1; i <= 100; i++)
	{
		s += i;
	}
	printf("%d\n", s);
	return 0;
}

2、求s=1+3+5+……+97+99的值。
#include <stdio.h>
int main(void)
{
	int s = 0, i = 0;
	for (i = 1; i <= 99; i = i + 2)
	{
		s += i;
	}
	printf("%d\n", s);
	return 0;
}

3、求s=1-3+5-7+……+97-99的值。
#include <stdio.h>
#include <math.h>
int main(void)
{
	int s = 0, i = 0;
	for (i = 1; i <= 50; i++)
	{
		s += (2 * i - 1) * pow(-1, i + 1);
	}
	printf("%d\n", s);
	return 0;
}

4、求π的值,已知π/4≈1-1/3+1/5-1/7+…… ,计算至某项的绝对值小于1E-6为止(1E-6表示的是浮点数,即1*10的-6次方)。
#include <stdio.h>
int main(void)
{
	double s = 0, j = 1, i = 0;
	for (i = 1; 1 / (2 * i - 1) >= 1e-6; i++)
	{
		s += j / (2 * i - 1);
		j = -j;
	}
	printf("π的值约为%lf\n", 4 * s);
	return 0;
}

5、求s=1+2!+3!+4!+……+19!+20! 的值(n!表示n的阶乘)。
#include <stdio.h>
int main(void)
{
	long long k = 1, sum = 0, i = 0;
	for (i = 1; i <= 20; i++)
	{
		k *= i;
		sum += k;
	}
	printf("%lld\n", sum);
	return 0;
}

6、求s=1+3!+5!+7!+……+17!+19!的值(n!表示n的阶乘)。
#include <stdio.h>
int main(void)
{
	long long s = 1, sum = 0, i = 0;
	for (i = 1; i <= 19; i++)
	{
		s *= i;
		if (i % 2 == 1) sum += s;
	}
	printf("%lld\n", sum);
	return 0;
}

7、任意输入x的值,求sinx≈x-x3/3!+x5/5!-x7/7!+……,直到某项的绝对值小于1E-6为止,最后输出sinx的值(1E-6表示的是浮点数,也就是1*10的-6次方)。
(1)版本一:若输入x的单位为角度:
#include <stdio.h>
#include <math.h>
int main(void)
{
	double x = 0, y = 0, i = 0, j = 1, jc = 1;//其中jc表示阶乘的值
	printf("输入x的值【角度】:");
	scanf("%lf", &x);
	x = x * 3.1415926 / 180;
	while (fabs(pow(-1, i) * pow(x, j) / jc) >= 0.000001)
	{
		y += pow(-1, i) * pow(x, j) / jc;
		i++;
		j += 2;
		jc *= (j - 1) * j;
	}
	printf("sinx = %lf\n", y);
	return 0;
}
(2)版本二:若输入x的单位为弧度:
#include <stdio.h>
#include <math.h>
int main(void)
{
	double i = 1, jc = 1, sum = 0, x = 0;
	printf("输入x的值【弧度】:");
	scanf("%lf", &x);
	while (pow(x, i) / jc >= 0.000001)
	{
		sum += pow(-1, (i - 1) / 2) * pow(x, i) / jc;
		i += 2;
		jc *= i * (i - 1);
	}
	printf("则sinx = %lf\n", sum);
	return 0;
}

8、已知s=1/1+2/1+3/2+5/3+8/5+……,求前40项之和。
#include <stdio.h>
int main(void)
{
	double a[41] = { 0 };
	int i = 0;
	double sum = 0;
	for (i = 0; i < 41; i++)
	{
		a[i] = (i == 0 || i == 1) ? 1 : a[i - 2] + a[i - 1];
	}
	for (i = 0; i < 40; i++)
	{
		sum += a[i + 1] / a[i];
	}
	printf("%lf\n", sum);
	return 0;
}

9、已知s=1+11+111+1111+……. 一直加到n位1,n的值自己输入。
#include <stdio.h>
int main(void)
{
	double sum = 0, k = 1;
	int i = 0, n = 0;
	printf("输入n的值:");
	scanf("%d", &n);
	for (i = 0; i < n ; i++)
	{
		sum += k;
		k = 10 * k + 1;
	}
	printf("%.0lf\n", sum);
	return 0;
}

10、已知s=1+12+123+1234+… 一直加到n位123…n,n的值自己输入。
#include <stdio.h>
int main(void)
{
	double ans = 0, s = 0;
	int i = 0, n = 0, m = 0;
	printf("输入n的值:");
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		for (m = 1; ; m *= 10)
		{
			if (i >= m && i < 10 * m )
			{
				s = 10 * m * s + i;
				break;
			}
		}
		ans += s;
	}
	printf("%.0lf\n", ans);
	return 0;
}

11、从键盘上输入若干学生的程序设计成绩,计算并输出所有学生的平均分和最高成绩。当输入负数的时候循环结束,再输出结果。
#include <stdio.h>
int main(void)
{
	int i = 0;
	double t = 0, ave = 0, sum = 0, max = 0;
	printf("输入各个学生的C语言成绩(输入负数时结束):\n");
	while (scanf("%lf", &t)) //scanf返回参数的个数,也就是1
	{
		if (t < 0) break;
		if (max < t) max = t;
		sum += t;
		i++;
	}
	ave = sum / i;
	printf("平均成绩为:%lf,最高成绩为:%lf\n", ave, max);
	return 0;
}

12、任意输入一个正整数,判断其是否是素数,所谓素数就是指质数。(建议使用2到3种方法来实现判断)。
(1)版本一:
#include <stdio.h>
int main(void)
{
	int n = 0, i = 0, flag = 1;
	printf("输入一个整数:");
	scanf("%d", &n);
	for (i = 2; i * i <= n; i++)
	{
		if (n % i == 0)
		{
			flag = 0;
			break;
		}
	}
	if (n <= 1 || flag == 0) printf("它不是质数\n");
	else printf("它是质数\n");
	return 0;
}
(2)版本二:
#include <stdio.h>
int main(void)
{
	int n = 0, i = 0;
	printf("输入一个整数:");
	scanf("%d", &n);
	for (i = 2; i < n; i++)
	{
		if (n % i == 0) break;
	}
	/*通过判断以上循环是否完成来确定输入的数是否质数*/
	if (i == n)	printf("它是质数\n");
	else printf("它不是质数\n");
	return 0;
}
(3)版本三:
#include <stdio.h>
int main(void)
{
	int x = 0, i = 0, n = 0;
	printf("输入一个整数:");
	scanf("%d", &x);
	for (i = 1; i <= x; i++)
	{
		if (x % i == 0) n++;
	}
	if (n == 2) printf("它是质数\n");
	else printf("它不是质数\n");
	return 0;
}


13、输出1000以内所有的质数。
#include <stdio.h>
int main(void)
{
	int x = 0, i = 0;
	for (x = 2; x <= 1000; x++)
	{
		int flag = 1;
		for (i = 2; i * i <= x; i++)
		{
			if (x % i == 0)
			{
				flag = 0;
				break;
			}
		}
		if (flag) printf("%d\n", x);
	}
	return 0;
}
拓展:质数筛
#include <iostream>
using namespace std;
const int N = 1e7 + 10;
int isprime[N + 10];
int main()
{
	//把N(N=1e7+10)以内的素数筛选出来  状态标记为1
	for (int i = 2; i <= N; i++)
	{
		isprime[i] = 1;
	}
	for (int i = 2; i * i <= N; i++)
	{
		if (isprime[i])
		{
			for (int j = i * i; j <= N; j += i)
			{
				isprime[j] = 0;
			}
		}
	}
	for (int i = 2; i <= 1000; i++) //输出1000以内的素数
	{
		if (isprime[i]) cout << i << endl;
	}
	return 0;
}

14、输入一个正整数,输出比它小的最大的最多的10个质数。
#include <stdio.h>
int main(void)
{
	int x = 0, i = 0, flag = 1, num = 0, z = 0;
	printf("输入一个正整数:");
	scanf("%d", &z);
	printf("比这个数小的最大的十个质数为:\n");
	for (x = z; x >= 2; x--)
	{
		flag = 1;
		for (i = 2; i * i <= x; i++)
		{
			if (x % i == 0)
			{
				flag = 0;
				break;
			}
		}
		if (flag == 1)//此条件值为真,证明了x是素数
		{
			num++;//先计算个数
			if (num <= 10) printf("%d\n", x);
			else break;//输出10个素数就终止循环!
		}
	}
	return 0;
}

15、任意输入2个正整数给自变量x和y,求它们的最大公约数和最小公倍数。
#include <stdio.h>
int main(void)
{
	int x = 0, y = 0, i = 0;
	printf("输入两个正整数:");
	scanf("%d%d", &x, &y);
	//求最大公约数
	for (i = x; i >= 1; i--)
	{
		if (x % i == 0 && y % i == 0)
			break;
	}
	printf("最大公约数:%d\n", i);
	printf("最小公倍数:%d\n", x * y / i);
	return 0;
}

16、爱因斯坦阶梯问题:设有一阶梯,每步跨2阶余1阶,每步跨3阶余2阶,每步跨5阶余4阶,每步跨6阶余5阶,每步跨7阶刚好到顶,问该阶梯一共有多少阶?
#include <stdio.h>
int main(void)
{
	int n = 1;
	while (!(n % 2 == 1 && n % 3 == 2 && n % 5 == 4 && n % 6 == 5 && n % 7 == 0))
	{
		n++;//求出的值为满足条件的最小值
	}
	printf("%d\n", n);
	return 0;
}

17、任意输入一个十进制整数,要求输出对应的二进制结果(最后结果表示为4个字节,即32位二进制的形式)。
#include <stdio.h>
int main(void)
{
	int x = 0, a[32] = { 0 }, i = 0, y = 0;
	printf("Input decimal number:");
	scanf("%d", &x); //带符号的32位二进制数转换为十进制的范围为[-2147483647,2147483647]
	if (x < 0) a[31] = 1;
	y = x > 0 ? x : -x; //将x的绝对值赋值给y
	while (y > 0)
	{
		a[i] = y % 2;
		i++;
		y = y / 2;
	}
	if (x < 0) //对于负数,这里计算的是负数的二进制补码
	{
		for (i = 30; i >= 0; i--)
		{
			a[i] = !a[i]; //除开符号位以外其余各位按位求反 1->0 0->1
		}
		a[0]++;		    //末位+1
		for (i = 1; i <= 30; i++) //处理进位
		{
			a[i] += a[i - 1] / 2;
			a[i - 1] = a[i - 1] % 2;
		}
		a[30] = a[30] % 2;
	}
	printf("Output binary number:");
	for (i = 31; i >= 0; i--)
	{
		printf("%d", a[i]);
	}
	return 0;
}

18、根据媒体发布的信息,2010年中国GDP总量为5.845万亿美元,增长率是10.1%;美国GDP总量是14.536万亿美元,增长率3.3%,在2个GDP增长率保持2010年的水平不变的情况下,编程计算到哪一年中国的GDP总量有望超过美国?
#include <stdio.h>
int main(void)
{
	int i = 2010;
	double m = 14.536, z = 5.845;
	while (m >= z)
	{
		z = z * 1.101;
		m = m * 1.033;
		i++;
	}
	printf("到%d年中国的GDP有望超过美国\n", i);
	return 0;
}

19、从键盘上任意输入2个正整数给a和b,计算a和b之间所有整数(包括a和b)的累加和,并输出结果。
#include <stdio.h>
int main(void)
{
	int a = 0, b = 0, t = 0, i = 0, sum = 0;
	printf("输入a和b的值(以空格分开):");
	scanf("%d%d", &a, &b);
	if (a > b) //保证a不大于b
	{
		t = a;
		a = b;
		b = t;
	}
	for (i = a; i <= b; i++) sum += i;
	printf("a到b的累加和为:%d\n", sum);
	return 0;
}

20、张三在10年前存了一笔钱准备用来购房,按照当时的房价,这笔钱可以买房150平方米。已知银行存款年利率为6%,房价却按照每年10%的速度增长,请编写程序,计算张三存的这笔钱现在能购买多少平米的房子?
#include <stdio.h>
int main(void)
{
	double s = 150, m = 1, i = 1;
	while (i <= 10)
	{
		m = m * 1.1;
		s = s * 1.06;
		i++;
	}
	printf("张三的存款现在可以购买%lf平米的房子\n", s / m);
	return 0;
}

21、某班级准备举行一次五子棋比赛,参赛选手每人之间必须进行一场对弈,进过统计发现一共进行了300场比赛,编程,计算并输出参赛的人数是多少?
#include <stdio.h>
int main(void)
{
	int n = 1, s = 0;
	while (s != 300)
	{
		n++;
		s = s + (n - 1); //握手定理
	}
	printf("%d\n", n);
	return 0;
}

22、输入1000以内所有的完数,所谓完数是指一个数值刚好是它的因子之和(但是因子中不包含本身),例如6=1+2+3,所以6就是完数。
#include <stdio.h>
int main(void)
{
	int x = 0, i = 0, s = 0;
	for (x = 1; x <= 1000; x++)
	{
		s = 0;
		for (i = 1; i <= x / 2; i++)
		{
			if (x % i == 0) s += i;
		}
		if (x == s) printf("%d\n", x);
	}
	return 0;
}

23、一个口袋中有3个红球,5个白球,6个黑球,从其中任意取出8个球,要求至少有一个白球。
(1)输出所有的可能组合。
(2)计算这些可能出现的概率是多少?可参考组合数的通项公式及递推公式:

C n m = n ! m ! ( n − m ) ! C n m = C n − 1 m + C n − 1 m − 1 \begin{aligned} &{C}_{n}^{m}=\frac{n!}{m!(n-m)!}& \\\\ &{C}_{n}^{m}={C}_{n-1}^{m}+{C}_{n-1}^{m-1}& \end{aligned} Cnm=m!(nm)!n!Cnm=Cn1m+Cn1m1

#include <stdio.h>
double C(int n, int m) //通过递归求解组合C(n,m)的值
{
	if (m == 0 || m == n)
		return 1;
	else
		return C(n - 1, m) + C(n - 1, m - 1);
}
int main(void)
{
	int white = 0, red = 0, black = 0;
	double p = 0;
	for (white = 1; white <= 5; white++) //要求至少有一个白球,所以white的值从1开始
	{
		for (red = 0; red <= 3; red++)
		{
			for (black = 0; black <= 6; black++)
			{
				p = C(5, white) * C(3, red) * C(6, black) / C(14, 8); //通过组合求概率
				if (white + red + black == 8)
					printf("%d个白球,%d个红球,%d个黑球的概率为:%lf\n", white, red, black, p);
			}
		}
	}
	return 0;
}

24、有若干只鸡兔同在一个笼子里,从上面数,有36个头,从下面数,有100只脚。问笼中各有多少只鸡和兔?
#include <stdio.h>
int main(void)
{
	int c = 0, r = 0, i = 0;
	for (c = 0; c <= 36; c++)
	{
		for (r = 0; r <= 36; r++)
		{
			if (2 * c + 4 * r == 100 && c + r == 36)
				printf("鸡:%d只 兔:%d只\n", c, r);
		}
	}
	return 0;
}

25、0-9可以组成多少个没有重复的3位偶数?这里没有重复的就是指该数值中每位上的数值互不相等。
#include <stdio.h>
int main(void)
{
	int i = 0, sum = 0, a1 = 0, a2 = 0, a3 = 0;
	for (i = 100; i <= 999; i++)
	{
		a1 = i % 10; //个位
		a2 = i / 10 % 10; //十位
		a3 = i / 100 % 10; //百位
		if (i % 2 == 0 && a1 != a2 && a1 != a3 && a2 != a3)
			sum++;
	}
	printf("%d\n", sum);
	return 0;
}

26、编写程序输出9*9乘法表。
#include <stdio.h>
int main(void)
{
	int i = 0, j = 0;
	for (i = 1; i <= 9; i++)
	{
		for (j = 1; j <= i; j++)
		{
			printf("%d*%d=%d\t", j, i, i * j);
		}
		printf("\n");
	}
	return 0;
}

27、求出用1元人民币兑换1分,2分,5分硬币的所有兑换方案,要求兑换硬币总数是70枚。
#include <stdio.h>
int main(void)
{
	int a = 0, b = 0, c = 0, sum = 0;
	for (a = 0; a <= 100; a++)
	{
		for (b = 0; b <= 50; b++)
		{
			for (c = 0; c <= 20; c++)
			{
				if (a + b + c == 70 && a + 2 * b + 5 * c == 100)
				{
					sum++;
					printf("第%d种方案:1分%d枚,2分%d枚,5分%d枚\n", sum, a, b, c);
				}
			}
		}
	}
	return 0;
}

28、水仙花数是指一个N位正整数(N≥3),它的每个位上的数字的N次幂之和等于它本身。例如:153=13+53+33。 本题要求编写两个函数,一个判断给定整数是否水仙花数,另一个按从小到大的顺序打印出给定区间(m,n)内所有的水仙花数。
#include <stdio.h>
int narcissistic(int number); //判断是否是水仙花数
void PrintN(int m, int n); //打印m和n之间的水仙花数
int main(void)
{
	int m = 0, n = 0;
	scanf("%d %d", &m, &n);
	PrintN(m, n);
	return 0;
}
int narcissistic(int number)
{
	int a[50] = { 0 }, i = 0, j = 0, sum = 0, k = 0, t = 1;
	int n = number;
	while (number > 0)
	{
		a[i++] = number % 10;
		number /= 10;
	}
	for (j = 0; j < i; j++)
	{
		t = 1;
		for (k = 0; k < i; k++)
			t *= a[j];
		sum += t;
	}
	if (sum == n) return 1;
	else return 0;
}
void PrintN(int m, int n)
{
	int i = 0;
	for (i = m + 1; i <= n - 1; i++)
	{
		if (narcissistic(i) == 1)
			printf("%d\n", i);
	}
}

29、输出以下图形(必须用循环的思想来解决)。
   *
  ***
 *****
*******
 *****
  ***
   *
#include <stdio.h>
int main(void)
{
	int k = 0, x = 0, i = 0;
	for (i = 1; i <= 4; i++) //第1至4行
	{
		for (k = 1; k <= 6 - i; k++)
			printf(" ");
		for (x = 1; x <= 2 * i - 1; x++)
			printf("*");
		printf("\n");
	}
	for (i = 3; i >= 1; i--) //第5至7行
	{
		for (k = 1; k <= 6 - i; k++)
			printf(" ");
		for (x = 1; x <= 2 * i - 1; x++)
			printf("*");
		printf("\n");
	}
	return 0;
}

30、某君从某年开始每年都举办一次生日party,并且每次都要吹熄与年龄相同根数的蜡烛。现在算起来,他一共吹熄了236根蜡烛。请问,他从多少岁开始过生日party的?
#include <stdio.h>
int main(void)
{
	int y = 0, sum = 0, i = 0;
	for (y = 1; y <= 236; y++)
	{
		sum = 0; //表示吹熄的蜡烛总数
		for (i = y; i <= 236; i++) //从第y岁开始吹
		{
			sum += i;
			if (sum == 236) printf("从%d岁开始过生日\n", y);
			else if (sum > 236) break;
		}
	} //运行结束后可以得到26和236两个答案,理论都可行,但236实际不可能,故答案为26
	return 0;
}

31、输入年月日,计算这天是该年的第几天。
#include<stdio.h>
int main(void)
{
	int year = 0, month = 0, day = 0, s = 0, i = 0;
	printf("输入年月日(中间用空格隔开): ");
	scanf("%d%d%d", &year, &month, &day);
	i = 1;
	while (i <= month - 1)        //计算所有整月的总天数
	{
		if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10)
			s = s + 31;
		else if (i == 4 || i == 6 || i == 9 || i == 11)
			s = s + 30;
		else if (i == 2)
			s = s + 28;
		i++;
	}
	s = s + day;                 //加上该非整月的day天
	if ((year % 4 == 0 && year % 100 != 0 || year % 400 == 0) && month >= 3)
		s++;                 //如果为闰年,并且月份在2月之后,则s+1
	printf("%d\n", s);
}

或者:

#include <iostream>
using namespace std;
int DayNum(int y, int m, int d)
{
	int num[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
	int ans = 0;
	for (int i = 1; i < m; i++) ans += num[i - 1];
	ans += d;
	if (((y % 4 == 0 && y % 100 != 0) || y % 400 == 0) && m >= 3) ans++;
	return ans;
}
int main()
{
	int year = 0, month = 0, day = 0;
	printf("输入年月日(中间用空格隔开): ");
	cin >> year >> month >> day;
	cout << DayNum(year, month, day) << endl;
	return 0;
}

32、输入一个起始年月日,再输入一个终止年月日,计算这2个日期之间一共有多少天?
#include<stdio.h>
int DateNumber(int year, int month, int day)
{
	//函数DateNumber的作用是计算日期year-month-day是该年的第几天
	int i = 1, s = 0;
	while (i <= month - 1)       //计算所有整月的总天数
	{
		if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10)
			s = s + 31;
		else if (i == 4 || i == 6 || i == 9 || i == 11)
			s = s + 30;
		else if (i == 2)
			s = s + 28;
		i++;
	}
	s = s + day;               //加上该日期所处非整月的day天
	if ((year % 4 == 0 && year % 100 != 0 || year % 400 == 0) && month >= 3)
		s++;               //如果为闰年,并且月份在2月之后,则s+1
	return s;
}
int main(void)
{
	int y1 = 0, m1 = 0, d1 = 0, y2 = 0, m2 = 0, d2 = 0, s1 = 0, s2 = 0, i = 0, result = 0;
	printf("输入起始年月日(用空格隔开): ");
	scanf("%d%d%d", &y1, &m1, &d1);
	printf("输入终止年月日(用空格隔开): ");
	scanf("%d%d%d", &y2, &m2, &d2);
	s1 = DateNumber(y1, m1, d1); //调用函数DateNumber计算日期y1-m1-d1处于y1年的第几天
	s2 = DateNumber(y2, m2, d2); //调用函数DateNumber计算日期y2-m2-d2处于y2年的第几天
	//总天数=起始年剩的天数+中间所有年的天数+终止年已经过了的天数
	result = 365 - s1 + 365 * (y2 - y1 - 1) + s2;//先默认都是平年,后面再纠正由于闰年带来的误差
	for (i = y1 + 1; i <= y2 - 1; i++)
	{
		if (i % 4 == 0 && i % 100 != 0 || i % 400 == 0)
			result++;
	}
	if ((y1 % 4 == 0 && y1 % 100 != 0 || y1 % 400 == 0) && (y1 != y2))
		result++;
	printf("从起始日至终止日共经过%d天\n", result);
	return 0;
}


33、任意输入一个年份,输出该年的日历(以下公式中的 [ ] 均代表取整)。
(1)公式一:输入年月日year-month-day,求出该日期在该年是第S天,再由S和year求出对应星期w。

{ w = [ y e a r − 1 ] + [ ( y e a r − 1 ) / 4 ] − [ ( y e a r − 1 ) / 100 ] + [ ( y e a r − 1 ) / 400 ] + S S = S ( y e a r , m o n t h , d a y ) \left\{ \begin{aligned} w&=[year-1]+[(year-1)/4]-[(year-1)/100]+[(year-1)/400]+S& \\\\ S&=S(year,month,day)& \end{aligned} \right. wS=[year1]+[(year1)/4][(year1)/100]+[(year1)/400]+S=S(year,month,day)

#include <stdio.h>
int DateToWeek(int year, int month, int day)
{
	int i = 1, s = 0, week = 0;
	while (i <= month - 1)       //计算所有整月的总天数
	{
		if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10)
			s = s + 31;
		else if (i == 4 || i == 6 || i == 9 || i == 11)
			s = s + 30;
		else if (i == 2)
			s = s + 28;
		i++;
	}
	s = s + day;               //加上该日期所处非整月的day天
	if ((year % 4 == 0 && year % 100 != 0 || year % 400 == 0) && month >= 3)
		s++;
	week = ((year - 1) + (year - 1) / 4 - (year - 1) / 100 + (year - 1) / 400 + s) % 7;
	return week;
}
int main(void)
{
	int y = 0, m = 0, d = 0, w = 0, i = 0;
	printf("  输入年份:");
	scanf("%d", &y);
	printf("\n");
	int Days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
	if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
		Days[1]++; //闰年2月加一天
	for (m = 1; m <= 12; m++)
	{
		printf("          %4d年%2d月\n", y, m);
		printf("  --------------------------\n");
		w = DateToWeek(y, m, 1); //该年每个月1号为星期w
		printf("  一  二  三  四  五  六  日\n"); //中式日历排版
		for (i = 1; i <= (w - 1 + 7) % 7; i++)
			printf("    ");  //每次循环打印4个空格,循环次数由w决定
		for (i = 1; i <= Days[m - 1]; i++)
		{
			printf("%4d", i);
			if ((w + i - 1 + 7) % 7 == 0)  //换行依据和w有关
				printf("\n");
		}
		printf("\n\n");
	}
	return 0;
}
(2)公式二:即蔡勒公式,输入年月日year-month-day,根据方程求出该日期对应星期w。

{ w = ( [ p 4 ] − 2 p + q + [ q 4 ] + [ 13 × ( m o n t h + 1 ) 5 ] + d a y − 1 )   m o d   7 p = [ y e a r 100 ] q = y e a r   m o d   100 \left\{ \begin{aligned} w&=([\frac{p}{4}]-2p+q+[\frac{q}{4}]+[\frac{13×(month+1)}{5}]+day-1)\bmod 7& \\\\ p&=[\frac{year}{100}]& \\\\ q &=year\bmod 100& \end{aligned} \right. wpq=([4p]2p+q+[4q]+[513×(month+1)]+day1)mod7=[100year]=yearmod100

#include <stdio.h>
int DateToWeek(int year, int month, int day)
{
	if (month == 1 || month == 2) //判断month是否为1或2 
	{
		year--;
		month += 12; //蔡勒公式需要把当年的1月和2月视作前一年的13月和14月
	}
	int ye = year / 100;
	int ar = year % 100;
	int week = ye / 4 - 2 * ye + ar + ar / 4 + 26 * (month + 1) / 10 + day - 1;
	while (week < 0)
		week += 7;
	week %= 7;
	return week;
}
int main(void)
{
	int y = 0, m = 0, d = 0, w = 0, i = 0;
	printf("  输入年份:");
	scanf("%d", &y);
	printf("\n");
	int Days[12] = { 31,28,31,30,31,30,31,31,30,31,30,31 };
	if (y % 4 == 0 && y % 100 != 0 || y % 400 == 0)
		Days[1]++; //闰年2月加一天
	for (m = 1; m <= 12; m++)
	{
		printf("          %4d年%2d月\n", y, m);
		printf("  --------------------------\n");
		w = DateToWeek(y, m, 1); //该年每个月1号为星期w
		printf("  日  一  二  三  四  五  六\n"); //西式日历排版
		for (i = 1; i <= w; i++)
			printf("    "); //每次循环打印4个空格,循环次数由w决定
		for (i = 1; i <= Days[m - 1]; i++)
		{
			printf("%4d", i);
			if ((w + i) % 7 == 0)
				printf("\n");
		}
		printf("\n\n");
	}
	return 0;
}


二、数组

1、输入一个寝室6位同学的身高,要求按照从小到大的顺序输出。
#include <stdio.h>
int main(void)
{
	double h[6] = { 0 }, t = 0;
	int i = 0, j = 0;
	for (i = 0; i <= 5; i++)
	{
		printf("输入第%d个同学的身高:", i + 1);
		scanf("%lf", &h[i]);
	}
	for (j = 0; j <= 4; j++)
	{
		for (i = 0; i <= 4 - j; i++)
		{
			if (h[i] > h[i + 1])
			{
				t = h[i];
				h[i] = h[i + 1];
				h[i + 1] = t;
			}
		}
	} //冒泡排序法,考试重点
	printf("从小到大排列为:\n");
	for (i = 0; i <= 5; i++) printf("%.2lf  ", h[i]);
	return 0;
}

2、输入某班级所有同学的程序设计技术期末成绩(人数是33人),要求输出最好的2位同学的成绩。
#include <stdio.h>
int main(void)
{
	double h[33] = { 0 }, t = 0;
	int i = 0, j = 0;
	for (i = 0; i <= 32; i++)
	{
		printf("输入第%d个同学的C语言成绩:", i + 1);
		scanf("%lf", &h[i]);
	}
	for (j = 0; j <= 31; j++)
	{
		for (i = 0; i <= 31 - j; i++)
		{
			if (h[i] > h[i + 1])
			{
				t = h[i];
				h[i] = h[i + 1];
				h[i + 1] = t;
			}
		}
	}
	printf("两个最好成绩为:%lf和%lf\n", h[31], h[32]);
	return 0;
}

3、学校举行校园歌手大赛,一共有n位裁判(n由自己输入),这n位裁判位为选手打分,去掉一个最高分和去掉一个最低分,再计算平均分就是该选手的最后得分,请编写程序模仿7位裁判为某位选手的打分过程。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	double t = 0, ave = 0, sum = 0;
	int i = 0, j = 0, n = 0;
	printf("输入裁判数量:");
	scanf("%d", &n);
	double* a = (double*)malloc(8 * n); //动态申请内存;
	for (i = 0; i <= n - 1; i++)
	{
		printf("请第%d个裁判打分:", i + 1);
		scanf("%lf", &a[i]);
	}
	for (j = 0; j <= n - 2; j++)
	{
		for (i = 0; i <= n - 2 - j; i++)
		{
			if (a[i] > a[i + 1])
			{
				t = a[i];
				a[i] = a[i + 1];
				a[i + 1] = t;
			}
		}
	}
	for (i = 1; i < n - 1; i++) sum += a[i];
	ave = sum / (n - 2); //计算平均分
	printf("去掉最高分和最低分,选手最后平均得分为%lf\n", ave);
	free(a);
	return 0;
}

4、任意输入10个数值,计算出它们的平均值,然后求得并输出与平均值最接近的数。
#include <stdio.h>
#include <math.h>
int main(void)
{
	double h[10] = { 0 }, k[10] = { 0 };
	double ave = 0, sum = 0, min = 0;
	int i = 0;
	for (i = 0; i <= 9; i++)
	{
		printf("输入第%d个同学的身高:", i + 1);
		scanf("%lf", &h[i]);
		sum = sum + h[i];
	}
	ave = sum / 10;
	printf("平均身高为%lf\n", ave);
	for (i = 0; i <= 9; i++)
		k[i] = fabs(h[i] - ave); 	//求出各身高与平均值的差的绝对值

	min = k[0];
	for (i = 1; i <= 9; i++)
	{
		if (min > k[i])
			min = k[i];	//求十个差值中的最小值
	}
	for (i = 0; i <= 9; i++)
	{
		if (fabs(ave - h[i]) == min) //找出满足要求的那个身高
			printf("与平均值最接近的身高为%lf\n", h[i]);
	}
	return 0;
}

5、输入班级33位同学的程序设计技术期末成绩(百分制,分数控制在0-100之间),分别统计优,良,中,及格,不及格等5种情况的人数,以及百分比。
#include <stdio.h>
int main(void)
{
	int x[33] = { 0 }, i = 0, a = 0, b = 0, c = 0, d = 0, e = 0;
	for (i = 0; i <= 32; i++)
	{
		printf("第%d个同学的成绩【0-100】为:", i + 1);
		scanf("%d", &x[i]);
		while (x[i] > 100 || x[i] < 0) //纠错功能
		{
			printf("你输入的分数不正确,请你重新输入第%d个同学的成绩[0,100]:", i + 1);
			scanf("%d", &x[i]);
		}
	}
	for (i = 0; i <= 32; i++)
	{
		if (90 <= x[i] && x[i] <= 100)
			a++;
		else if (80 <= x[i])
			b++;
		else if (70 <= x[i])
			c++;
		else if (60 <= x[i])
			d++;
		else if (0 <= x[i])
			e++;
	}
	printf("优秀%d人,占比%lf%%\n", a, (double)a / 33 * 100);
	printf("良好%d人,占比%lf%%\n", b, (double)b / 33 * 100);
	printf("中等%d人,占比%lf%%\n", c, (double)c / 33 * 100);
	printf("及格%d人,占比%lf%%\n", d, (double)d / 33 * 100);
	printf("不及格%d人,占比%lf%%\n", e, (double)e / 33 * 100);
	return 0;
}

6、将一个整数逆序排列并输出。
#include <stdio.h>
int main(void)
{
	int x = 0, k = 0, a = 0;
	printf("输入一个整数:");
	scanf("%d", &k);
	x = k > 0 ? k : -k;
	printf("逆序排列后为:");
	if (k < 0) printf("-");
	if (k == 0) printf("0");
	while (x > 0)
	{
		a = x % 10;
		printf("%d", a);
		x = x / 10;
	}
	return 0;
}

7、FIBONACCI数列,已知该数列的第1个数值是1,第2个数值也是1,从第3个数值开始,每个数值等于其前2个数值之和,请编程输出该数列的前40项。
#include <stdio.h>
int main(void)
{
	int a[40] = { 0 }, i;
	for (i = 0; i <= 39; i++)
	{
		a[i] = (i == 0 || i == 1) ? 1 : a[i - 1] + a[i - 2];
		printf("%d\n", a[i]);
	}
	return 0;
}

8、编写程序,请给一个一维数组任意输入6个整数,例如:假设输入如下数值:
7 		4	 	8 		9 		1 		5
要求建立一个具有如下内容的方阵并输出:
5		7 		4	 	8 		9 		1
1		5		7 		4	 	8 		9
9		1		5		7 		4	 	8
8		9		1		5		7 		4
4		8		9		1		5		7
7		4		8		9		1		5
#include <stdio.h>
int main(void)
{
	int a[6][6] = { 0 };
	int i = 0, j = 0, m = 0;
	printf("任意输入六个数值:");
	for (i = 0; i <= 5; i++)
		scanf("%d", &a[5][i]);
	for (i = 0; i <= 5; i++)
	{
		for (j = 0; j <= 5; j++)
		{
			for (m = 0; m <= 5; m++)
			{
				if (i - j == 5 - m || i - j == -1 - m) 	//计算二维数组各个变量的值
					a[i][j] = a[5][m];
			}
		}
	}
	for (i = 0; i <= 5; i++)
	{
		for (j = 0; j <= 5; j++)
		{
			printf("%d\t", a[i][j]); //二维数组的矩阵形式输出
		}
		printf("\n");
	}
	return 0;
}

9、请编写程序实现功能:从键盘上输入6名学生的5门成绩,分别统计出每个学生的平均成绩和总成绩,并输出。
#include <stdio.h>
int main(void)
{
	double s[6][7] = { 0 };
	int i = 0, j = 0;
	for (i = 0; i < 6; i++)
	{
		printf("输入第%d位同学的5门成绩(以空格分开):", i + 1);
		for (j = 0; j < 5; j++)
		{
			scanf("%lf", &s[i][j]);
			s[i][5] += s[i][j];
		}
		s[i][6] = s[i][5] / 5;
	}
	printf("\n");
	printf("%-10s", "科目");
	printf("%-10s", "高数");
	printf("%-10s", "思修");
	printf("%-10s", "英语");
	printf("%-10s", "离散");
	printf("%-10s", "C语言");
	printf("%-10s", "总分");
	printf("%-10s", "平均分");
	printf("\n");
	for (i = 0; i < 6; i++)
	{
		printf("%-10s", "成绩");
		for (j = 0; j < 7; j++)
		{
			printf("%-10.0lf", s[i][j]);
		}
		printf("\n");
	}
	return 0;
}

10、任意输入3行4列的矩阵中的所有值,求转置矩阵。
#include <stdio.h>
int main(void)
{
	int a[3][4] = { 0 }, b[4][3] = { 0 }, i = 0, j = 0;
	printf("输入3行4列的矩阵的值:\n");
	for (i = 0; i <= 2; i++)
	{
		for (j = 0; j <= 3; j++)
		{
			scanf("%d", &a[i][j]);
		}
	}
	for (i = 0; i <= 2; i++)
	{
		for (j = 0; j <= 3; j++)
		{
			b[j][i] = a[i][j];
		}
	}
	printf("其转置矩阵为:\n");
	for (j = 0; j <= 3; j++)
	{
		for (i = 0; i <= 2; i++)
		{
			printf("%d\t", b[j][i]);
		}
		printf("\n");
	}
	return 0;
}

11、任意输入一个二维数组4行5列的所有制,找到并输出该二维数组中最大值及其位置。
#include <stdio.h>
int main(void)
{
	int a[4][5] = { 0 }, i = 0, j = 0, t = 0, max = 0;
	printf("输入4行5列矩阵的值:\n");
	for (i = 0; i <= 3; i++)
	{
		for (j = 0; j <= 4; j++)
		{
			scanf("%d", &a[i][j]);
		}
	}
	max = a[0][0];
	for (i = 0; i <= 3; i++)
	{
		for (j = 0; j <= 4; j++)
		{
			if (a[i][j] > max)
			{
				max = a[i][j];
			}
		}
	}
	for (i = 0; i <= 3; i++)
	{
		for (j = 0; j <= 4; j++)
		{
			if (a[i][j] == max)
			{
				printf("最大值为a[%d][%d]=%d\n", i, j, max);
			}
		}
	}
	return 0;
}

12、编写程序输出n行n列的杨辉三角。n的值自己输入,如下所示:
输入:
5
输出:
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
#include <stdio.h>
int main(void)
{
	int a[100][100] = { 0 }, i = 0, j = 0, n = 0;
	printf("输入n的值:");
	scanf("%d", &n);
	printf("%d行%d列的杨辉三角为:\n", n, n);
	for (i = 0; i <= n - 1; i++)
	{
		for (j = 0; j <= i; j++)
		{
			if (j == 0 || i == j)
				a[i][j] = 1;
			else
				a[i][j] = a[i - 1][j] + a[i - 1][j - 1];
		}
	}
	for (i = 0; i <= n - 1; i++)
	{
		for (j = 0; j <= i; j++)
		{
			printf("%d\t", a[i][j]);
		}
		printf("\n");
	}
	return 0;
}

13、鞍点(Saddle point)在微分方程中,沿着某一方向是稳定的,另一条方向是不稳定的奇点,叫做鞍点。在泛函中,既不是极大值点也不是极小值点的临界点,叫做鞍点。在矩阵中,一个数在所在行中是最大值,在所在列中是最小值,则被称为鞍点。在物理上要广泛一些,指在一个方向是极大值,另一个方向是极小值的点。输入n行n列的矩阵,求出鞍点。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	int i = 0, j = 0, n = 0, m = 0, x = 0, y = 0, min = 0, max = 0, flag = 0;
	printf("输入矩阵的行数m和列数n:");
	scanf("%d%d", &m, &n);
	int** a;
	a = (int**)malloc(sizeof(int*) * m);
	for (i = 0; i < m; i++)
		a[i] = (int*)malloc(sizeof(int) * n); //为m行n列的二维数组动态开辟空间
	printf("输入矩阵各个元素的值(以空格分隔):\n");
	for (i = 0; i <= m - 1; i++)
	{
		for (j = 0; j <= n - 1; j++)
			scanf("%d", &a[i][j]);
	}
	for (i = 0; i <= m - 1; i++)
	{
		for (j = 0; j <= n - 1; j++)
		{
			max = a[i][0];
			for (y = 0; y <= n - 2; y++)
			{
				if (a[i][y] < a[i][y + 1])
					max = a[i][y + 1];
			}
			min = a[0][j];
			for (x = 0; x <= m - 2; x++)
			{
				if (a[x][j] > a[x + 1][j])
					min = a[x + 1][j];
			}
			if (max == a[i][j] && min == a[i][j])
			{
				printf("YES,鞍点值为%d,坐标为第%d行第%d列\n", a[i][j], i, j);
				flag = 1;
			}
		}
	}
	if (flag == 0) printf("NO\n");
	for (i = 0; i < m; i++) free(a[i]);
	free(a);
	return 0;
}

14、任意输入一段英文,统计其中英文字符a的个数,不区分大小写。
#include <stdio.h>
#include <string.h>
int main(void)
{
	char E[5000];
	int sum = 0, i = 0;
	printf("输入一段英文:");
	gets(E);
	for (i = 0; i <= strlen(E) - 1; i++)
	{
		if (E[i] == 'A' || E[i] == 'a')
			sum++;
	}
	printf("英文字符a(不区分大小写)的个数是%d\n", sum);
	return 0;
}

15、任意输入一段英文,分别统计出其中26个英文字母各自的个数,不区分大小写。
#include <stdio.h>
#include <string.h>
int main(void)
{
	char E[5000];
	int sum = 0, i = 0, j = 0;
	printf("输入一段英文:");
	gets(E);
	for (j = 65; j <= 90; j++) //这里是A到Z在ASCII码表中的范围
	{
		sum = 0;
		for (i = 0; i <= strlen(E) - 1; i++)
		{
			if (E[i] == j || E[i] == j + 32) //对数组E中每个位置上的字符进行依次判断属于A 或者 a
				sum++;
		}
		printf("英文字符%c的个数是%d\n", j, sum);
	}
	return 0;
}

16、任意输入一段英文,分别统计出英文字符、数字字符、空格字符和其他字符等四大类字符各自的个数。
#include <stdio.h>
#include <string.h>
int main(void)
{
	char E[5000];
	int a = 0, b = 0, c = 0, d = 0, i = 0;
	printf("输入一段英文:");
	gets(E);
	for (i = 0; i <= strlen(E) - 1; i++)
	{
		if (E[i] >= 'A' && E[i] <= 'Z' || E[i] >= 'a' && E[i] <= 'z')
			a++;
		else if (E[i] >= '0' && E[i] <= '9')
			b++;
		else if (E[i] == ' ')
			c++;
		else
			d++;
	}
	printf("英文字符个数是%d\n", a);
	printf("数字字符个数是%d\n", b);
	printf("空格字符个数是%d\n", c);
	printf("其他字符个数是%d\n", d);
	return 0;
}

17、任意输入一段英文,统计其中英文单词的个数。
#include <stdio.h>
#include <string.h>
int main(void)
{
	char E[5000];
	int sum = 0, i = 0;
	printf("输入一段英文:");
	gets(E);
	sum = 0;
	for (i = 0; i <= strlen(E) - 1; i++)
	{
		if (E[i] >= 65 && E[i] <= 90 || E[i] >= 97 && E[i] <= 122) //左边是英文字母
			if (!(E[i + 1] >= 65 && E[i + 1] <= 90 || E[i + 1] >= 97 && E[i + 1] <= 122)) //右边不是英文字母
				if (E[i + 1] != '-') //右边也不是符号"-"
					sum++;
	}
	printf("单词个数是%d\n", sum);
	return 0;
}

18、任意输入一段英文,将其中所有的数字字符删除,再输出结果(删除功能采用的是后面往前覆盖的思路设计)。
#include <stdio.h>
#include <string.h>
void delete_zf(char zfc[])
{
	int i = 0, j = 0, n = 0;
	n = strlen(zfc); //计算字符串长度
	for (i = 0; i < n; i++)
	{
		if (zfc[i] >= '0' && zfc[i] <= '9')
		{
			for (j = i + 1; j <= n; j++)
			{
				zfc[j - 1] = zfc[j];	//从i+1位置开始到n位置的字符整体往前覆盖
			}
			i--; //删除之后i不能变,因为它这个位置放的是后面覆盖过来的且没有判断过的字符
		}
	}
}
int main(void)
{
	char zfc[1000], del;
	printf("输入一段英文:");
	gets(zfc);
	delete_zf(zfc);
	printf("输出删除数字字符之后的英文:");
	puts(zfc);
	return 0;
}

19、从键盘上任意输入一个字符串,将该字符串中的字符按照ASCII码的顺序从小到大的顺序排序后输出。
#include <stdio.h>
#include <string.h>
int main(void)
{
	int n = 0, i = 0, j = 0, t = 0;
	char a[1000];
	printf("输入一个字符串:\n");
	gets(a);
	n = strlen(a);
	for (j = 0; j <= n - 2; j++)
	{
		for (i = 0; i <= n - 2 - j; i++)
		{
			if (a[i] > a[i + 1])
			{
				t = a[i];
				a[i] = a[i + 1];
				a[i + 1] = t;
			}
		}
	}
	printf("该字符串按照ASCII码的顺序从小到大的顺序排序为:\n");
	puts(a);
	return 0;
}

20、编程实现输入一行字符,将其中重复出现的字符全部删除。例如:若输入字符串:abcdabghakdmncdgkp,则删除重复字符后应输出:abcdghkmnp。
#include <stdio.h>
#include <string.h>
int main(void)
{
	int n = 0, i = 0, j = 0, k = 0;
	char a[1000];
	printf("输入一个字符串:\n");
	gets(a);
	n = strlen(a);
	for (i = 1; i <= n - 1; i++)
	{
		for (j = 0; j <= i - 1; j++)
		{
			if (a[i] == a[j])
			{
				for (k = i + 1; k <= n - 1; k++)
				{
					a[k - 1] = a[k];
				}
				n--; //删除某个重复字母后,更新当前的字符数组长度
				i--; //防止遇到连续相同字符时漏删
			}
		}
	}
	printf("该字符串删除重复元素后为:\n");
	for (k = 0; k <= n - 1; k++)
	{
		printf("%c", a[k]);
	}
	return 0;
}


三、自定义函数

1、任意输入一个整数,编写一个函数isPrimeNumber用来判断输入的整数是否是素数。
#include <stdio.h>
int isPrimeNumber(int s)
{
	int i = 0;
	if (s <= 1) return 0;
	for (i = 2; i * i <= s; i++)
	{
		if (s % i == 0) return 0;
	}
	return 1;
}
int main(void)
{
	int n = 0;
	printf("输入一个整数:");
	scanf("%d", &n);
	if (isPrimeNumber(n)) printf("这个数是素数\n");
	else printf("这个数不是素数\n");
	return 0;
}

2、编写函数求Fibonacci数列的第n项的值,然后在主函数中调用该函数输出第n项的值。
(1)递归法,效率低:
#include <stdio.h>
double fib(int n)
{
	return (n == 1 || n == 2) ? 1 : fib(n - 1) + fib(n - 2);
}
int main(void)
{
	int n = 0;
	printf("输入一个正整数:");
	scanf("%d", &n);
	printf("斐波那契数列第%d项为:%.0lf\n", n, fib(n));
	return 0;
}
(2)迭代法,效率高:
#include <stdio.h>
int main(void)
{
	double f1 = 0, f2 = 1, fn = 0;
	int i = 0, n = 0;
	printf("输入一个正整数:");
	scanf("%d", &n);
	for (i = 1; i <= n; i++)
	{
		fn = f1 + f2;
		f1 = f2, f2 = fn;
	} //迭代法求斐波那契数列
	printf("%.0lf", f1);
	return 0;
}

3、编写排序的函数sort,实现调用该函数对任意一组数据进行从小到大的顺序排序(建议使用冒泡排序法的格式书写)。
(1)冒泡排序法:
#include <stdio.h>
#include <stdlib.h>
void bubble_sort(int* q, int l, int r)
{
	if (l >= r) return;
	int i = 0, j = 0;
	for (i = 0; i < r - l; i++)
	{
		int flag = 0;
		for (j = 0; j < r - l - i; j++)
		{
			if (q[j] > q[j + 1])
			{
				int temp = q[j];
				q[j] = q[j + 1];
				q[j + 1] = temp;
				flag = 1;
			}
		}
		if (flag == 0) return; //对冒泡排序的优化
	}
}
int main(void)
{
	int n = 0, i = 0;
	printf("输入元素个数:");
	scanf("%d", &n);
	int* p = (int*)malloc(sizeof(int) * n);
	printf("输入各元素:");
	for (i = 0; i < n; i++) scanf("%d", &p[i]);
	bubble_sort(p, 0, n - 1);
	printf("排序后:");
	for (i = 0; i < n; i++) printf("%d ", p[i]);
	return 0;
}
(2)快速排序法:
#include <stdio.h>
#include <stdlib.h>
void quick_sort(int* q, int l, int r)
{
	if (l >= r) return;
	int x = q[l + (r - l) / 2], i = l - 1, j = r + 1;
	while (i < j)
	{
		while (q[++i] < x);
		while (q[--j] > x);
		if (i < j)
		{
			int temp = q[i];
			q[i] = q[j];
			q[j] = temp;
		}
	}
	quick_sort(q, l, j);
	quick_sort(q, j + 1, r);
}
int main(void)
{
	int n = 0, i = 0;
	printf("输入元素个数:");
	scanf("%d", &n);
	int* p = (int*)malloc(sizeof(int) * n);
	printf("输入各元素:");
	for (i = 0; i < n; i++) scanf("%d", &p[i]);
	quick_sort(p, 0, n - 1);
	printf("排序后:");
	for (i = 0; i < n; i++) printf("%d ", p[i]);
	return 0;
}
(3)归并排序法:
#include <stdio.h>
#include <stdlib.h>
void merge_sort(int* q, int l, int r)
{
	if (l >= r) return;
	int* temp = (int*)malloc(sizeof(int) * (r - l + 1));
	int mid = l + (r - l) / 2;
	merge_sort(q, l, mid);
	merge_sort(q, mid + 1, r);
	int k = 0, i = l, j = mid + 1;
	while (i <= mid && j <= r)
	{
		if (q[i] <= q[j]) temp[k++] = q[i++];
		else temp[k++] = q[j++];
	}
	while (i <= mid) temp[k++] = q[i++];
	while (j <= r) temp[k++] = q[j++];
	for (i = l, j = 0; i <= r; i++, j++) q[i] = temp[j];

}
int main(void)
{
	int n = 0, i = 0;
	printf("输入元素个数:");
	scanf("%d", &n);
	int* p = (int*)malloc(sizeof(int) * n);
	printf("输入各元素:");
	for (i = 0; i < n; i++) scanf("%d", &p[i]);
	merge_sort(p, 0, n - 1);
	printf("排序后:");
	for (i = 0; i < n; i++) printf("%d ", p[i]);
	return 0;
}

4、任意输入一个正整数n,求n!(例如5!=1 *2 *3 *4 *5),要求将求n!的过程写成自定义函数。
(1)利用循环求解:
#include <stdio.h>
double fact(int n)
{
	double  s = 1;
	while (n--) s *= (n + 1);
	return s;
}
int main(void)
{
	int n = 0;
	printf("输入一个正整数:");
	scanf("%d", &n);
	printf("%d的阶乘为:%.0lf\n", n, fact(n));
	return 0;
}

或者:

#include <stdio.h>
double fact(int n)
{
	double  s = 1;
	for (; n >= 1; n--)
		s *= n;
	return s;
}
int main(void)
{
	int n = 0;
	printf("输入一个正整数:");
	scanf("%d", &n);
	printf("%d的阶乘为:%.0lf\n", n, fact(n));
	return 0;
}
(2)利用递归求解:
#include <iostream>
#include <iomanip>
using namespace std;
double fact(int n)
{
	return (n == 0 || n == 1) ? 1 : (n * fact(n - 1));
}
int main(void)
{
	int n = 0;
	cin >> n;
	cout << fixed << setprecision(0) << fact(n) << endl; //不以科学记数法输出,保留0位小数
	return 0;
}


5、汉诺塔(又称河内塔)问题是源于印度一个古老传说的益智玩具。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,每次移动一个圆盘,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘,柱子可以编号为A B C,编程输出n个圆盘从A柱子移动到C柱子的步骤。

汉诺塔游戏:把所有盘子从A移动到C

解题思路:
(1)把A柱子上的前N-1个盘子借助C柱子,全部移动到B柱子上(过程暂不考虑),再把第N个盘子由A柱子移动到C柱子上,那么剩下要移动的盘子在B柱子上了。
(2)把B柱子上的前N-2个盘子借助C柱子,全部移动到A柱子上(过程暂不考虑),再把第N-1个盘子由B柱子移动到C柱子上。
(3)重复上面的两个步骤即可把A柱子上的盘子全部移动到C柱子上。

#include <stdio.h>
void loveyou(int n, char start, char help, char end)
{
	if (n >= 2)
	{
		loveyou(n - 1, start, end, help);
		printf("%c------>%c\n", start, end);
		loveyou(n - 1, help, start, end);
	}
	else if (n == 1)
	{
		printf("%c------>%c\n", start, end);
	}
}
int main(void)
{
	int n = 0;
	printf("输入圆盘的数量:");
	scanf("%d", &n);
	loveyou(n, 'A', 'B', 'C');
	return 0;
}

6、任意输入一段英文,分别统计出英文字符、数字字符、空格字符和其他字符等四大类字符各自的个数。要求将统计四大类字符个数的过程书写为自定义函数,输入、调用函数、输出结果放在主函数中完成。
#include <stdio.h>
#include <string.h>
int a = 0, b = 0, c = 0, d = 0;
void tjzf(char E[])
{
	int i = 0;
	for (i = 0; i <= strlen(E) - 1; i++)
	{
		if (E[i] >= 'A' && E[i] <= 'Z' || E[i] >= 'a' && E[i] <= 'z')
			a++;
		else if (E[i] >= '0' && E[i] <= '9')
			b++;
		else if (E[i] == ' ')
			c++;
		else
			d++;
	}
}
int main(void)
{
	char F[1000];
	printf("输入一段英文:");
	gets(F);
	tjzf(F);
	printf("英文字符个数是%d\n", a);
	printf("数字字符个数是%d\n", b);
	printf("空格字符个数是%d\n", c);
	printf("其他字符个数是%d\n", d);
	return 0;
}

7、一个班级有n位同学(n为正整数,由自己输入),输入他们的程序设计技术期末考试成绩,要求将求所有人的平均分功能、求最高分功能、最低分功能分别写成3个自定义函数。
#include <stdio.h>
#include <stdlib.h>
double getmax(double a[], int n)
{
	double max = a[0];
	int i = 0;
	for (i = 1; i < n; i++)
	{
		if (max < a[i]) max = a[i];
	}
	return max;
}
double getmin(double a[], int n)
{
	double min = a[0];
	int i = 0;
	for (i = 1; i < n; i++)
	{
		if (min > a[i]) min = a[i];
	}
	return min;
}
double getave(double a[], int n)
{
	double sum = 0, ave = 0;
	int i = 0;
	for (i = 0; i < n; i++) sum += a[i];
	ave = sum / n;
	return ave;
}
int main(void)
{
	int n = 0, i = 0;
	printf("输入班级人数:");
	scanf("%d", &n);
	double* a = (double*)malloc(8 * n);
	printf("输入所有同学的成绩:\n");
	for (i = 0; i < n; i++) scanf("%lf", &a[i]);
	printf("最高分为%.2lf,最低分为%.2lf,平均分为%.2lf\n", getmax(a, n), getmin(a, n), getave(a, n));
	return 0;
}

8、输入2个正整数给x和y,求得这2个数值的最大公约数和最小公倍数,(要求求最大公约数和求最小公倍数的功能必须分别用自定义函数来完成)。
#include <stdio.h>
int gys(int x, int y)
{
	int i = 0;
	for (i = x; i >= 1; i--)
	{
		if (x % i == 0 && y % i == 0) return i;
	}
	return 1;
}
int gbs(int x, int y)
{
	int i = 0;
	for (i = x; i <= x * y; i++)
	{
		if (i % x == 0 && i % y == 0) return i;;
	}
	return 1;
}
int main(void)
{
	int a = 0, b = 0;
	printf("输入两个正整数:");
	scanf("%d%d", &a, &b);
	printf("它们的最大公约数为%d,最小公倍数为%d\n", gys(a, b), gbs(a, b));
	return 0;
}

9、验证歌德巴赫猜想:输入一个任何一个不小于6的偶数,它可以表示为两个素数之和,也就是两个质数之和(要求判断某个数是否是素数的过程用自定义函数来实现)。
#include <stdio.h>
int isPrimeNumber(int s)
{
	int i = 0;
	if (s <= 1) return 0;
	for (i = 2; i * i <= s; i++)
	{
		if (s % i == 0) return 0;
	}
	return 1;
}
int main(void)
{
	int i = 0, k = 0;
	printf("输入一个不小于4的偶数:");
	scanf("%d", &k);
	while (k % 2 != 0 || k < 4)
	{
		printf("输入错误,请重新输入:");
		scanf("%d", &k);
	}
	for (i = 2; i <= k - 2; i++)
	{
		if (isPrimeNumber(i) == 1 && isPrimeNumber(k - i) == 1)
		{
			printf("%d+%d=%d\n", i, k - i, k);
			break;
		}
	}
	return 0;
}

10、小明刚刚看完电影《第39级台阶》,离开电影院的时候,他数了数礼堂前的台阶数,恰好是39级!站在台阶前,他突然又想着一个问题:如果我每一步只能迈上1个或2个台阶。先迈左脚,然后左右交替,最后一步是迈右脚,也就是说一共要走偶数步。那么,上完39级台阶,有多少种不同的上法呢?请编写程序计算并输出结果。
#include <stdio.h>
int sf = 0;
void f(int n, int step)
{
	if (n > 39) return;
	if (n == 39 && step % 2 == 0) sf++;
	f(n + 1, step + 1);
	f(n + 2, step + 1);
}
int main(void)
{
	f(0, 0);
	printf("共有%d种上法\n", sf);
	return 0;
}

11、角谷定理。输入一个自然数,若为偶数,则把它除以2,若为奇数,则把它乘以3加1。经过如此有限次运算后,总可以得到自然数值1。求经过多少次可得到自然数1(要求此题用函数的递归调用方法实现)。
#include <stdio.h>
int pd(int s, int sum) //sum表示次数
{
	if (s == 1) return sum;
	else if (s > 1 && s % 2 == 0)
	{
		sum++;
		pd(s / 2, sum);
	}
	else if (s > 1 && s % 2 == 1)
	{
		sum++;
		pd(3 * s + 1, sum);
	}
	else return -1;
}
int main(void)
{
	int a = 0;
	printf("输入一个自然数:");
	scanf("%d", &a);
	printf("至少需经过%d次运算可以得到自然数1\n", pd(a, 0));
	return 0;
}


四、指针

1、从键盘输入一个字符串,要求找出大写字母、小写字母、空格、数字和其他字符各自的数量(必须用指针来完成)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
	int a = 0, b = 0, c = 0, d = 0, i = 0;
	char* E = (char*)malloc(5000);
	printf("输入一段英文:");
	gets(E);
	for (i = 0; i <= strlen(E) - 1; i++)
	{
		if (*(E + i) >= 'A' && *(E + i) <= 'Z' || *(E + i) >= 'a' && *(E + i) <= 'z')
			a++;
		else if (*(E + i) >= '0' && *(E + i) <= '9')
			b++;
		else if (*(E + i) == ' ')
			c++;
		else
			d++;
	}
	printf("英文字符个数是%d\n", a);
	printf("数字字符个数是%d\n", b);
	printf("空格字符个数是%d\n", c);
	printf("其他字符个数是%d\n", d);
	return 0;
}

2、输入n个整数(n由自己输入),要求输出最大值和最小值(必须用指针来完成)。
(1)普通版:
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	double t = 0;
	int i = 0, j = 0, n = 0;
	printf("输入数据个数:");
	scanf("%d", &n);
	double* p = (double*)malloc(8 * n);
	printf("输入这%d个数据:", n);
	for (i = 0; i < n; i++)
		scanf("%lf", p + i);
	for (j = n - 2; j >= 0; j--)
	{
		for (i = 0; i <= j; i++)
		{
			if (*(p + i) < *(p + i + 1))
			{
				t = *(p + i);
				*(p + i) = *(p + i + 1);
				*(p + i + 1) = t;
			}
		}
	}
	printf("从高到低排序后输出:\n");
	for (i = 0; i < n; i++)
		printf("%lf\t", *(p + i));
	free(p);
	return 0;
}
(2)自定义函数版:
#include <stdio.h>
#include <stdlib.h>
void input(double* p, int n) //输入函数
{
	int i = 0;
	printf("输入%d个数据:", n);
	for (i = 0; i <= n - 1; i++)
		scanf("%lf", p + i);
}
void output(double* p, int n) //输出函数
{
	int i = 0;
	printf("按从高到低排序并输出:\n");
	for (i = 0; i < n; i++)
		printf("%lf\n", *(p + i));
}
void sort(double* p, int n) //排序函数
{
	int i = 0, j = 0;
	double t = 0;
	for (j = n - 2; j >= 0; j--)
	{
		for (i = 0; i <= j; i++)
		{
			if (*(p + i) < *(p + i + 1))
			{
				t = *(p + i);
				*(p + i) = *(p + i + 1);
				*(p + i + 1) = t;
			}
		}
	}
}
int main(void) //主函数
{
	int n = 0;
	printf("输入数据的个数:");
	scanf("%d", &n);
	double* p = (double*)malloc(sizeof(double) * n);
	input(p, n);
	sort(p, n);
	output(p, n);
	free(p);
	return 0;
}

3、输入10个整数,存入一维数组a中。要求设计一个函数move,实现如下功能:使数组a中前面各个元素顺序向后移动m个位置,最后m个数变成最前面的m个数(要求此题必须用自定义函数外加指针来实现数据的移动)。
#include <stdio.h>
int main(void)
{
	int m = 0, i = 0, j = 0, t = 0;
	int a[10] = { 0 };
	printf("输入10个整数:");
	for (i = 0; i < 10; i++) scanf("%d", a + i);
	printf("输入需要移动的数据个数:");
	scanf("%d", &m);
	for (j = 1; j <= m; j++)
	{
		t = *(a + 9);
		for (i = 8; i >= 0; i--)
		{
			*(a + i + 1) = *(a + i);
		}
		*(a + 0) = t;
	}
	for (i = 0; i < 10; i++)
	{
		printf("%d ", *(a + i));
	}
	return 0;
}

4、自定义一个函数,将一个十进制正整数转换为对应的二进制数(必须用指针来完成)。
(1)数组版(转换为补码):
#include <stdio.h>
void DecToBin(int x) //正负数都可以转换,这里转换成对应的二进制补码
{
	int a[32] = { 0 }, i = 0, y = 0;
	if (x < 0) a[31] = 1;	
	y = x > 0 ? x : -x; //将x的绝对值赋值给y
	while (y > 0)
	{
		a[i] = y % 2;
		i++;
		y = y / 2;
	}
	if (x < 0) //对于负数,这里计算的是负数的二进制补码
	{
		for (i = 30; i >= 0; i--)
		{
			a[i] = !a[i]; //除开符号位以外其余各位按位求反 1->0 0->1
		}
		a[0]++;		    //末位+1
		for (i = 1; i <= 30; i++) //处理进位
		{
			a[i] += a[i - 1] / 2;
			a[i - 1] = a[i - 1] % 2;
		}
		a[30] = a[30] % 2;
	}
	for (i = 31; i >= 0; i--)
	{
		printf("%d", a[i]);
	}
}
int main(void)
{
	int k = 0;
	printf("Input decimal number:");
	scanf("%d", &k); //带符号的32位二进制数转换为十进制的范围为[-2147483647,2147483647]
	printf("Output binary number:");
	DecToBin(k);
	return 0;
}
(2)指针版(转换为原码):
#include <stdio.h>
#include <stdlib.h>
void DecToBin(int x) //正负数都可以转换,这里转换成对应的二进制原码
{
	int i = 0, y = 0;
	int* a = (int*)malloc(4 * 32);
	for (i = 0; i <= 31; i++)
	{
		*(a + i) = 0;
	}
	if (x < 0)
		*(a + 31) = 1; //为负数定义符号位
	y = x > 0 ? x : -x; //y取x的绝对值
	i = 0; //给i重新赋值为0
	while (y > 0)
	{
		*(a + i) = y % 2;
		i++;
		y = y / 2;
	}
	for (i = 31; i >= 0; i--)
	{
		printf("%d", *(a + i));
	}
	free(a);
}
int main(void)
{
	int k = 0;
	printf("Input decimal number:");
	scanf("%d", &k);
	printf("Output binary number:");
	DecToBin(k);
	return 0;
}

5、自定义一个函数,删除一个字符串中从第n个字符开始的连续m个字符(必须用指针来完成)。
#include <stdio.h>
#include <string.h>
void delete_zf(char* zf, int n, int m)
{
	int i = 0, c;
	c = strlen(zf);
	for (i = 0; i <= c - n - m; i++)
	{
		*(zf + n + i) = *(zf + n + i + m);
	}
}
int main(void)
{
	char zfc[1000];
	int m = 0, n = 0;
	printf("输入一段字符串:");
	gets(zfc);
	printf("从第多少个字符开始删除:");
	scanf("%d", &n);
	printf("删除多少个字符:");
	scanf("%d", &m);
	delete_zf(zfc, n - 1, m);
	printf("输出结果:");
	puts(zfc);
	return 0;
}

6、n个学生围成圈(n由自己输入),从第1个同学开始报数,(报数的方式是1,2,3),其中报到3的同学出列,重复之,直到最后只剩下一个同学为止。编程求得这个同学的原本的是第几个同学?(必须用指针来实现)。
(1)数组版(跳出数字默认为3):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	int n, i = 0, k = 3, t = 0, num = 0; //总人数n,跳出数字k
	printf("输入总人数:");
	scanf("%d", &n);
	int* ar = (int*)malloc(4 * n);
	for (i = 0; i <= n - 1; i++) //给n个人编号
	{
		ar[i] = i + 1;
	}
	num = n; //num用来临时存放总人数
	for (i = 1;; i++) //终止条件置空实现无限循环
	{
		if (i > n) //回溯,转完一圈了
		{
			i = 1;
		}
		if (ar[i - 1] != 0) //不为跳出数字k的同学跳过
		{
			t++;
		}
		if (t == k)
		{
			ar[i - 1] = 0; //出列的同学赋值为0
			num--; //同时当前总人数减1
			t = 0; //又重新开始计数
		}
		if (num == 1)	//只剩一人时跳出循环
		{
			break;
		}
	}
	for (i = 0; i < n; i++) //打印目标值,最后编号不为0的同学就是剩下的那个
	{
		if (ar[i] != 0)
		{
			printf("这个同学原本是第%d个同学\n", ar[i]);
			break;
		}
	}
	return 0;
}
(2)指针版(跳出数字默认为3):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	int n, k = 3, i = 0, t = 0, num = 0; //总人数n,跳出数字k
	printf("输入总人数:");
	scanf("%d", &n);
	int* ar = (int*)malloc(4 * n);
	for (i = 0; i < n; i++) //给n个人编号
	{
		*(ar + i) = i + 1;
	}
	num = n; //num用来临时存放总人数
	for (i = 1;; i++) //终止条件置空实现无限循环
	{
		if (i > n)	//回溯,转完一圈了
			i = 1;
		if (*(ar + i - 1) != 0) //不为跳出数字k的同学跳过
			t++;
		if (t == k)
		{
			*(ar + i - 1) = 0; //出列的同学赋值为0
			num--; //同时当前总人数减1
			t = 0; //又重新开始计数
		}
		if (num == 1)	//只剩一人时跳出循环
		{
			break;
		}
	}
	for (i = 0; i < n; i++) //打印目标值,最后编号不为0的同学就是剩下的那个
	{
		if (*(ar + i) != 0)
		{
			printf("这个同学原本是第%d个同学\n", ar[i]);
			break;
		}
	}
	return 0;
}
(3)拓展(跳出数字由自己输入):
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	int n, k, i = 0, t = 0, num = 0; //总人数n,跳出数字k
	printf("输入总人数和跳出数字:");
	scanf("%d%d", &n, &k);
	int* ar = (int*)malloc(4 * n);
	for (i = 0; i <= n - 1; i++) //给n个人编号
	{
		ar[i] = i + 1;
	}
	num = n; //num用来临时存放总人数
	for (i = 1;; i++) //终止条件置空实现无限循环
	{
		if (i > n) //回溯,转完一圈了
		{
			i = 1;
		}
		if (ar[i - 1] != 0) //不为跳出数字k的同学跳过
		{
			t++;
		}
		if (t == k) //出列的同学赋值为0
		{
			ar[i - 1] = 0;
			num--; //同时总人数减1
			t = 0; //又重新开始计数
		}
		if (num == 1)	//只剩一人时跳出循环
		{
			break;
		}
	}
	for (i = 0; i < n; i++) //打印目标值,最后编号不为0的同学就是剩下的那个
	{
		if (ar[i] != 0)
		{
			printf("这个同学原本是第%d个同学\n", ar[i]);
			break;
		}
	}
	return 0;
}


五、结构体

1、声明4个结构体类型来描述学生,其成员包括:学号、姓名、性别、C语言课程成绩。再定义一个结构体变量,从键盘输入各成员具体的数据,然后输出。
#include <stdio.h>
int main(void)
{
	struct Student
	{
		int number;
		char name[11];
		char gender[5];
		double cscore;
	};
	struct Student stu;
	printf("输入学号:");
	scanf("%d", &stu.number);
	getchar();
	printf("输入姓名:");
	gets(stu.name);
	printf("输入性别:");
	gets(stu.gender);
	printf("输入C语言成绩:");
	scanf("%lf", &stu.cscore);
	printf("%-11s", "学号");
	printf("%-11s", "姓名");
	printf("%-11s", "性别");
	printf("%-11s", "C语言成绩");
	printf("\n");
	printf("%-11d", stu.number);
	printf("%-11s", stu.name);
	printf("%-11s", stu.gender);
	printf("%-11.2lf", stu.cscore);
	printf("\n");
	return 0;
}

2、声明一个结构体类型来表示日期,其成员包括:年、月、曰,编写一个函数用于计算某日是本年中的第几天?
#include <stdio.h>
int date_num(int y, int m, int d)
{
	int s = 0, i = 1;
	while (i <= m - 1)
	{
		if (i == 1 || i == 3 || i == 5 || i == 7 || i == 8 || i == 10)
			s = s + 31;
		else if (i == 4 || i == 6 || i == 9 || i == 11)
			s = s + 30;
		else if (i == 2)
			s = s + 28;
		i++;
	}
	s = s + d;
	if ((y % 4 == 0 && y % 100 != 0 || y % 400 == 0) && m >= 3)
		s++;
	return s;
}
int main(void)
{
	int num = 0;
	struct Date
	{
		int year;
		int month;
		int day;
	};
	struct Date date1;
	printf("输入年份:");
	scanf("%d", &date1.year);
	printf("输入月份:");
	scanf("%d", &date1.month);
	printf("输入日期:");
	scanf("%d", &date1.day); //日期没做纠错功能,输入时请输入合法日期
	num = date_num(date1.year, date1.month, date1.day);
	printf("这一天是该年的第%d天\n", num);
	return 0;
}

3、某班有7名学生,均选修了C语言课程,要求统计该班C语言课程成绩不及格的学生人数,并输出不及格学生的信息(包括学号、姓名、性别、C语言课程成绩)。
#include <stdio.h>
#include <string.h>
#include <windows.h>
#define H 200
struct Student
{
	int number;
	char name[11];
	char gender[5];
	double cscore;
};
struct Student stu[H];
void add_information()
{
	system("cls");
	int i = 0, sel = 0;
	struct Student tem_stu;
	printf("\n");
	printf("\t\t\t|———————————————————————————|\n");
	printf("\t\t\t|                欢迎来到信息录入功能                  |\n");
	printf("\t\t\t|———————————————————————————|\n");
	printf("\n");
	for (i = 0; i < H; i++)
	{
		if (stu[i].number == 0)
		{
			printf("\t\t\t接下来请继续选择您的操作:\n");
			printf("\t\t\t|------------------------|\n");
			printf("\t\t\t|   1 录入学生信息       |\n");
			printf("\t\t\t|------------------------|\n");
			printf("\t\t\t|   2 返回主菜单         |\n");
			printf("\t\t\t|------------------------|\n");
			printf("\t\t\t请输入您的选择【1-2】:");
			scanf("%d", &sel);
			while (sel < 1 || sel>2)
			{
				printf("\t\t\t输入错误,请重新输入您的选择【1-2】:");
				scanf("%d", &sel);
			}
			if (sel == 1)
			{
				int flag = 0;
				printf("\t\t\t输入学号:");
				scanf("%d", &tem_stu.number);
				getchar();
				printf("\t\t\t输入姓名:");
				gets(tem_stu.name);
				printf("\t\t\t输入性别:");
				gets(tem_stu.gender);
				printf("\t\t\t输入C语言成绩:");
				scanf("%lf", &tem_stu.cscore);
				for (i = 0; i < H; i++)
				{
					if (tem_stu.number == stu[i].number)
					{
						printf("\t\t\t该学号已存在!信息添加失败!!!\n");
						flag = 1;
						break;
					}
				}
				if (flag == 0)
				{
					for (i = 0; i < H; i++)
					{
						if (stu[i].number == 0)
						{
							stu[i] = tem_stu;
							printf("\t\t\t信息添加成功!!!\n\n");
							break;
						}
					}
				}
			}
			else if (sel == 2)
			{
				return;
			}
		}
	}
}
void show_information()
{
	system("cls");
	int i = 0;
	printf("\n");
	printf("\t\t\t|———————————————————————————|\n");
	printf("\t\t\t|                欢迎来到信息显示功能                  |\n");
	printf("\t\t\t|———————————————————————————|\n");
	printf("\n");
	printf("\t\t\t全部名单:\n");
	printf("\t\t\t|-------------------------------------------|\n");
	printf("\t\t\t| %-12s", "学号");
	printf("%-10s", "姓名");
	printf("%-10s", "性别");
	printf("%-10s|", "C语言成绩");
	printf("\n");
	printf("\t\t\t|-------------------------------------------|\n");
	for (i = 0; i < H; i++)
	{
		if (stu[i].number != 0)
		{
			printf("\t\t\t| %-12d", stu[i].number);
			printf("%-10s", stu[i].name);
			printf("%-10s", stu[i].gender);
			printf("%-10.2lf|", stu[i].cscore);
			printf("\n");
			printf("\t\t\t|-------------------------------------------|\n");
		}
		else
			break;
	}
	printf("\n\t\t\t不及格名单:\n");
	printf("\t\t\t|-------------------------------------------|\n");
	printf("\t\t\t| %-12s", "学号");
	printf("%-10s", "姓名");
	printf("%-10s", "性别");
	printf("%-10s|", "C语言成绩");
	printf("\n");
	printf("\t\t\t|-------------------------------------------|\n");
	for (i = 0; i < H; i++)
	{
		if (stu[i].number != 0)
		{
			if (stu[i].cscore < 60)
			{
				printf("\t\t\t| %-12d", stu[i].number);
				printf("%-10s", stu[i].name);
				printf("%-10s", stu[i].gender);
				printf("%-10.2lf|", stu[i].cscore);
				printf("\n");
				printf("\t\t\t|-------------------------------------------|\n");
			}
		}
		else
			break;
	}
	printf("\t\t\t");
	system("pause");
}
void menu()
{
	int sel = 0;
	system("cls");
	printf("\t\t\t****************** 欢迎您!尊贵的Sniper ****************\n\n");
	printf("\t\t\t请选择您的操作:\n");
	printf("\t\t\t|———————————————————————————|\n");
	printf("\t\t\t|                1   信息录入                          |\n");
	printf("\t\t\t|------------------------------------------------------|\n");
	printf("\t\t\t|                2   信息显示                          |\n");
	printf("\t\t\t|------------------------------------------------------|\n");
	printf("\t\t\t|                0   退出                              |\n");
	printf("\t\t\t|———————————————————————————|\n");
	printf("\t\t\t请输入您的选择【0-2】:");
	scanf("%d", &sel);
	getchar();
	while (sel < 0 || sel>2)
	{
		printf("\t\t\t输入错误,请重新输入你的选择【0-2】:");
		scanf("%d", &sel);
	}
	switch (sel)
	{
	case 1:
		add_information();
		menu();
		break;
	case 2:
		show_information();
		menu();
		break;
	case 0:
		exit(0);
	}
}
int main(void)
{
	system("color 70");
	menu();
	return 0;
}

4、己知一个班有5名学生,本学期学习了三门课程,分别为C语言、高数和英语。
(1)输出每一门课程的平均成绩;
(2)输出总成绩最高的学生的信息(包括学号、姓名、性别、3门课程的成绩以及总成绩);
(3)按C语言课程的成绩从高到低对全班学生进行排序,并输出排序后的结果。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct student
{
	int xh;
	char xm[11];
	char xb[3];
	double cscore;
	double gscore;
	double yscore;
};
struct student stu[5], jh;
int main(void)
{
	int i = 0, j = 0;
	for (i = 0; i <= 4; i++)
	{
		if (stu[i].xh == 0)
		{
			printf("输入第%d名学生的信息\n", i + 1);
			printf("学号:");
			scanf("%d", &stu[i].xh);
			getchar();
			printf("姓名:");
			gets(stu[i].xm);
			printf("性别:");
			gets(stu[i].xb);
			printf("C语言成绩:");
			scanf("%lf", &stu[i].cscore);
			printf("高数成绩:");
			scanf("%lf", &stu[i].gscore);
			printf("英语成绩:");
			scanf("%lf", &stu[i].yscore);
			printf("\n");
		}
	}
	printf("所有学生信息:\n");
	printf("%-11s", "学号");
	printf("%-11s", "姓名");
	printf("%-11s", "性别");
	printf("%-11s", "C语言成绩");
	printf("%-11s", "高数成绩");
	printf("%-11s", "英语成绩");
	printf("\n");
	for (i = 0; i <= 4; i++)
	{
		printf("%-11d", stu[i].xh);
		printf("%-11s", stu[i].xm);
		printf("%-11s", stu[i].xb);
		printf("%-11.2lf", stu[i].cscore);
		printf("%-11.2lf", stu[i].gscore);
		printf("%-11.2lf", stu[i].yscore);
		printf("\n");
	}
	printf("\n");
	double sum_c = 0, sum_g = 0, sum_y = 0, ave_c, ave_g, ave_y;	/*六个量分别表示C程.高数.英语的全班总分及平均分*/
	double zf[5] = { 0 }, t = 0;		/*数组zf存储每个人的总分*/
	for (i = 0; i <= 4; i++)
	{
		zf[i] = stu[i].cscore + stu[i].gscore + stu[i].yscore;
		sum_c += stu[i].cscore;
		sum_g += stu[i].gscore;
		sum_y += stu[i].yscore;
	}
	ave_c = sum_c / 5;
	ave_g = sum_g / 5;
	ave_y = sum_y / 5;
	printf("C语言平均成绩为:%.2lf\n", ave_c);
	printf("高数平均成绩为:%.2lf\n", ave_g);
	printf("英语平均成绩为:%.2lf\n", ave_y);
	for (j = 0; j <= 3; j++)
	{
		for (i = 0; i <= 3 - j; i++)
		{
			if (zf[i] > zf[i + 1])
			{
				t = zf[i];
				zf[i] = zf[i + 1];
				zf[i + 1] = t;
			}
		}
	}
	printf("\n");
	printf("总成绩分最高的学生信息:\n");
	printf("%-11s", "学号");
	printf("%-11s", "姓名");
	printf("%-11s", "性别");
	printf("%-11s", "C语言成绩");
	printf("%-11s", "高数成绩");
	printf("%-11s", "英语成绩");
	printf("%-11s", "总成绩");
	printf("\n");
	for (i = 0; i <= 4; i++)
	{
		if (stu[i].cscore + stu[i].gscore + stu[i].yscore == zf[4])
		{
			printf("%-11d", stu[i].xh);
			printf("%-11s", stu[i].xm);
			printf("%-11s", stu[i].xb);
			printf("%-11.2lf", stu[i].cscore);
			printf("%-11.2lf", stu[i].gscore);
			printf("%-11.2lf", stu[i].yscore);
			printf("%-11.2lf", zf[4]);
			printf("\n");
		}
	}
	for (j = 0; j <= 3; j++)
	{
		for (i = 0; i <= 3 - j; i++)
		{
			if (stu[i].cscore < stu[i + 1].cscore)
			{
				jh = stu[i];
				stu[i] = stu[i + 1];
				stu[i + 1] = jh;
			}
		}
	}
	printf("\n");
	printf("按C语言成绩进行由高到低排序:\n");
	printf("%-11s", "学号");
	printf("%-11s", "姓名");
	printf("%-11s", "性别");
	printf("%-11s", "C语言成绩");
	printf("%-11s", "高数成绩");
	printf("%-11s", "英语成绩");
	printf("\n");
	for (i = 0; i <= 4; i++)
	{
		printf("%-11d", stu[i].xh);
		printf("%-11s", stu[i].xm);
		printf("%-11s", stu[i].xb);
		printf("%-11.2lf", stu[i].cscore);
		printf("%-11.2lf", stu[i].gscore);
		printf("%-11.2lf", stu[i].yscore);
		printf("\n");
	}
	return 0;
}


六、数据读取和数据存储

1、编程统计文本文件"data.txt"中字符’$'出现的次数,并将统计的次数结果写入文本文件"res.txt"中。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	FILE* fp;
	FILE* fq;
	int n = 0;
	char ch;
	fp = fopen("data.txt", "r"); //需要提前创建源程序当前目录下的data.txt文件,否则会文件打开失败
	fq = fopen("res.txt", "w");
	if (fp == NULL)
	{
		printf("文件data.txt打开失败,请在源程序目录下手动创建该文件!\n");
		exit(0);
	}
	while (!feof(fp)) //feof()函数的功能是检测流上的文件结束符,如果文件结束,则返回非0值;如果文件未结束,则返回0值
	{
		ch = fgetc(fp);
		if (ch == '$')
			n++;
	}
	fprintf(fq, "%d", n); //将n的结果写入到res.txt文档中
	printf("%d\n", n); //将n的结果显示到屏幕中
	fclose(fp);
	fclose(fq);
	return 0;
}

2、从源程序当前目录下名为“xhar2.txt”的文本文件中读取前10个字符,依次显示在屏幕上,如果文本文件中不足10个字符,则有多少个字符读取多少个字符,并显示在屏幕上。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	FILE* fp;
	int n = 0;
	char ch;
	fp = fopen("xhar2.txt", "r"); //需要提前创建源程序当前目录下的data.txt文件,否则会文件打开失败
	if (fp == NULL)
	{
		printf("文件xhar2.txt打开失败,请在源程序目录下手动创建该文件!\n");
		exit(0);
	}
	while (!feof(fp))
	{
		n++;
		ch = fgetc(fp);
		printf("%c", ch);
		if (n == 10) break;
	}
	fclose(fp);
	return 0;
}

3、有2个磁盘文件a.txt和b.txt,要求产生一个新的文件c.txt,将b.txt中的数据追加到a.txt后面,再一并存入到c.txt中。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main(void)
{
	FILE* fa;
	FILE* fb;
	FILE* fc;
	int n = 0;
	char ch, ck;
	fa = fopen("a.txt", "a");
	fb = fopen("b.txt", "r");	//"b.txt"文档需要提前手动创建
	if (fb == NULL)
	{
		printf("文件b.txt打开失败,请在源程序目录下手动创建该文件!\n");
		exit(0);
	}
	while ((ch = fgetc(fb)) != EOF)
	{
		fputc(ch, fa);
	}
	fclose(fa); //关闭以"a"文件操作方式打开的a.txt
	fa = fopen("a.txt", "r"); //再以"r"文件操作方式重新打开a.txt
	fc = fopen("c.txt", "w");
	while ((ck = fgetc(fa)) != EOF)
	{
		fputc(ck, fc);
	}
	fclose(fc);
	fclose(fa);
	fclose(fb);
	printf("运行成功,打开文件查看吧!\n");
	return 0;
}

4、编写程序将全班同学的姓名、地址和电话号码写入到一个文件class.txt中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 200
struct Student
{
	char name[15];
	char address[30];
	char phone_number[15];
};
struct Student stu[N];
int main(void)
{
	int i = 0, sel = 0, M = 0;
	for (i = 0; i < N; i++)
	{
		printf("输入第%d个学生的信息:\n", i + 1);
		printf("姓名:");
		gets(stu[i].name);
		printf("地址:");
		gets(stu[i].address);
		printf("联系方式:");
		gets(stu[i].phone_number);
		printf("---------------------\n");
		printf("是否继续输入?\n");
		printf("1 是  2 否\n");
		printf("输入你的选择:");
		scanf("%d", &sel);
		getchar();
		while (sel < 1 || sel>2)
		{
			printf("输入错误,请重新输入:");
			scanf("%d", &sel);
			getchar();
		}
		printf("---------------------\n");
		if (sel == 1)
			continue;
		else if (sel == 2)
		{
			M = i + 1;
			break;
		}
	}
	FILE* fp;
	fp = fopen("class.txt", "w");
	if (fp == NULL)
	{
		printf("文件打开失败!");
		exit(0);
	}
	fprintf(fp, "%-9s%-28s%-15s\n", "姓名", "地址", "联系方式");
	for (i = 0; i < M; i++)
	{
		fprintf(fp, "%-9s%-28s%-15s\n", stu[i].name, stu[i].address, stu[i].phone_number);
	}
	//如果需要从文件中读取信息可以先利用rewind(fp)重置文件指针,再通过fscanf()函数读取,用法与fprintf()类似
	fclose(fp);
	printf("信息保存成功!请打开文件class.txt查看!\n");
	return 0;
}

5、从文件data.txt中读取2个正整数,计算这2个正整数之间所有正整数的和(包括本身),最后将结束写入到文件he.txt中。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	FILE* fp, * fq;
	int sum = 0, i = 0, a = 0, b = 0, t = 0;
	fp = fopen("data.txt", "r");
	fq = fopen("result.txt", "w");
	if (fp == NULL || fq == NULL)
	{
		printf("文件data.txt打开失败,请在源程序目录下手动创建该文件!\n");
		exit(0);
	}
	fscanf(fp, "%d", &a);
	fscanf(fp, "%d", &b);
	if (a > b)//a与b的值交换,必须保证计算中a小b大
	{
		t = a;
		a = b;
		b = t;
	}
	for (i = a; i <= b; i++)
	{
		sum += i;
	}
	fprintf(fq, "%d\n", sum);//输出到文件中
	fclose(fp);
	fclose(fq);
	printf("信息保存成功!请打开文件he.txt查看!\n");
	return 0;
}

6、从键盘上读取3个字符串,依次写入名为“string.txt"的文本文件。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
	char s[100], c[100], t[100];
	FILE* fp;
	if ((fp = fopen("string.txt", "w")) == NULL)
	{
		printf("文件string.txt打开失败,请在源程序目录下手动创建该文件!\n");
		exit(0);
	}
	fscanf(stdin, "%s%s%s", s, c, t); //空格和回车一样都被作为一个字符串结束的标志
	fprintf(fp, "%s %s %s", s, c, t);
	fclose(fp);
	printf("信息保存成功!请打开文件class.txt查看!\n");
	return 0;
}

7、从English.txt文件中读取一段英文,统计单词个数,然后将结果存入result.txt中。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void)
{
	FILE* fp, * fq;
	char E[5000];
	int sum = 0, i = 0;
	fp = fopen("English.txt", "r");
	fq = fopen("result.txt", "w");
	if (fp == NULL || fq == NULL)
	{
		printf("文件English.txt打开失败,请在源程序目录下手动创建该文件!\n");
		exit(0);
	}
	fgets(E, 5000, fp);
	for (i = 0; i <= strlen(E) - 1; i++)
	{
		if (E[i] >= 65 && E[i] <= 90 || E[i] >= 97 && E[i] <= 122)
			if (!(E[i + 1] >= 65 && E[i + 1] <= 90 || E[i + 1] >= 97 && E[i + 1] <= 122))
				if (E[i + 1] != '-')
					sum++;
	}
	fprintf(fq, "单词个数是%d\n", sum);
	fclose(fp);
	fclose(fq);
	printf("信息保存成功!请打开文件result.txt查看!\n");
	return 0;
}


七、基础算法题

1、利用欧几里得算法(又称为辗转相除法)快速计算2个整数的最大公约数。
参考公式:

g c d ( a , b ) = g c d ( b , a   m o d   b ) {gcd(a,b)}={gcd(b,a \bmod b)} gcd(a,b)=gcd(b,amodb)

示例代码:
#include <stdio.h>
int gcd(int a, int b)
{
	return (b == 0) ? a : gcd(b, a % b);
}
int main(void)
{
	int x = 0, y = 0;
	printf("Input two positive integers:");
	scanf("%d%d", &x, &y);
	printf("Output their greatest common divisor:%d", gcd(x, y));
	return 0;
}

2、大数相加:计算两个非负整数A、B的和。不过这一次有些特殊,A、B可能会很大。
输入格式:

第一行输入一个非负整数A。
第二行输入一个非负整数B。
A、B的长度不大于1000。

输出格式:

输出A+B的值。不要有多余的前导零。

样例输入:
1234567891011121314151617181920123456789
5974994545148254725545124662176431426461421426416
样例输出:
num1:   1234567891011121314151617181920123456789
num2:   5974994545148254725545124662176431426461421426416
num1Len:40
num2Len:49
 sum:   5974994546382822616556245976328048608381544883205
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100010
int main(void)
{
	int A = 0, B = 0, max = 0, i = 0;
	char a[N];
	char b[N];
	//以字符串形式输入加数和被加数
	printf("Please input two non-negative integers:\n");
	scanf("%s", a);
	scanf("%s", b);
	A = strlen(a);
	B = strlen(b);
	printf("num1:\t%s\n", a);
	printf("num2:\t%s\n", b);
	printf("num1Len:%d\n", A);      //输出非负整数num1的长度
	printf("num2Len:%d\n", B);  	//输出非负整数num2的长度
	max = A > B ? A : B;            //取num1和num2较大一个数的位数为max
	char* c = (char*)malloc(sizeof(char) * max);
	char* d = (char*)malloc(sizeof(char) * max);
	int* s = (int*)malloc(sizeof(int) * (max + 1)); //数组s存放答案
	for (i = max; i >= 0; i--) s[i] = 0;

	for (i = 0; i <= max - A - 1; i++) c[i] = '0';
	for (i = max - A; i < max ; i++) c[i] = a[i - max + A];
	for (i = 0; i <= max - B - 1; i++) d[i] = '0';
	for (i = max - B; i < max ; i++) d[i] = b[i - max + B];

	//按照竖式相加算法对数据进行运算
	for (i = max - 1; i >= 0; i--)
	{   //逐位相加并赋值给数组s的各个元素,暂时不处理进位
		s[max - 1 - i] = (c[i] - 48) + (d[i] - 48); 
	}
	for (i = max - 1; i >= 0; i--)
	{
		if (s[max - 1 - i] >= 10)
		{
			s[max - 1 - i] = s[max - 1 - i] % 10; //处理进位
			s[max - i]++;
		}
	}
	//对结果进行输出
	printf(" sum:\t");
	if (s[max] != 0)            
	{   //如果数组s最后一个元素有来自低位的进位 ,则输出 
		for (i = max; i >= 0; i--)
		{
			printf("%d", s[i]);
		}
	}
	else if (s[max] == 0)      
	{   //如果数组s最后一个元素没有来自低位的进位 ,则不输出
		for (i = max - 1; i >= 0; i--)
		{
			printf("%d", s[i]);
		}
	}
	return 0;
}
C++版本:
#include <iostream>
#include <cstdio>
#include <vector>
#include <string>
using namespace std;
vector<int> Add(vector<int>& A, vector<int>& B)
{
	vector<int> C;
	int t = 0;
	for (int i = 0; i < A.size() || i < B.size(); i++)
	{
		if (i < A.size()) t += A[i];
		if (i < B.size()) t += B[i];
		C.push_back(t % 10);
		t /= 10;
	}
	if (t) C.push_back(1);
	return C;
}
int main()
{
	string a, b;
	vector<int> A, B;
	cin >> a >> b;
	for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
	for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
	vector<int> C = Add(A, B);
	for (int i = C.size() - 1; i >= 0; i--) printf("%d", C[i]);
	return 0;
}

3、大数相乘:计算两个非负整数A、B的乘积。A、B可能会很大。
输入格式:

第一行输入一个非负整数A。
第二行输入一个非负整数B。
A、B的长度不大于1000。

输出格式:

输出A×B的值。不要有多余的前导零。

样例输入:
9876543210123456789103
15656489879654321156632157    
样例输出:
num1:    9876543210123456789103
num2:    15656489879654321156632157
num1Len:22
num2Len:26
product: 154631998815266502735860414063580937236496985171
示例代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 100010
int main(void)
{
	int A = 0, B = 0, i = 0, j = 0;
	char a[N];
	char b[N];
	//以字符串形式输入乘数和被乘数
	printf("Please input two non-negative integers:\n");
	scanf("%s", a);
	scanf("%s", b);
	A = strlen(a);
	B = strlen(b);
	printf("num1:\t %s\n", a);
	printf("num2:\t %s\n", b);
	printf("num1Len:%d\n", A);           //输出非负整数num1的长度
	printf("num2Len:%d\n", B);			 //输出非负整数num2的长度
	//为数据准备存放位置
	int* e = (int*)malloc(4 * A);
	for (i = 0; i < A; i++) e[i] = a[i] - 48;
	int* f = (int*)malloc(4 * B);
	for (i = 0; i < B; i++) f[i] = b[i] - 48;
	int* t = (int*)malloc(4 * (A + B));  //t存放结果
	for (i = 0; i <= A + B - 1; i++) t[i] = 0;
	//二维数组s为乘法竖式运算过程中的数据提供存放位置,s为B行A+B-1列的二维数组
	int** s = (int**)malloc(sizeof(int*) * B);
	for (i = 0; i < B; i++)
		s[i] = (int*)malloc(sizeof(int) * (A + B - 1));
	for (i = 0; i <= B - 1; i++)
	{
		for (j = 0; j <= A + B - 2; j++)
		{
			s[i][j] = 0;
		}
	}
	//按照乘法竖式算法对数据进行运算
	for (i = 0; i <= B - 1; i++)
	{
		for (j = A + B - 2 - i; j >= B - 1 - i; j--)
		{
			s[i][j] = e[i + j - B + 1] * f[B - 1 - i];
		}
	}
	for (j = 0; j <= A + B - 2; j++)
	{
		for (i = 0; i <= B - 1; i++)
		{
			t[j + 1] = t[j + 1] + s[i][j];
		}
	}
	for (j = A + B - 1; j >= 1; j--)
	{
		if (t[j] >= 10)
		{
			t[j - 1] = t[j - 1] + t[j] / 10;  //处理进位
			t[j] = t[j] % 10;
		}
	}
	//输出结果
	printf("product: ");
	for (i = 0; i <= A + B - 1; i++)
	{
		if (t[i] == 0 && i != A + B - 1) continue;
		else if (t[i] == 0 && i == A + B - 1) printf("0");
		else if (t[i] != 0)
		{
			for (; i <= A + B - 1; i++)
			{
				printf("%d", t[i]);
			}
			break;
		}
	}
	return 0;
}
C++版本:
#include <iostream>
#include <vector>
#include <string>
using namespace std;
vector<int> Mul(vector<int>& A, vector<int>& B)
{
	vector<int> C(A.size() + B.size(), 0); // 初始化为0,且999*99最多5位
	for (int i = 0; i < A.size(); i++)
	{
		for (int j = 0; j < B.size(); j++)
		{
			C[i + j] += A[i] * B[j];
		}
	}
	int t = 0;
	for (int i = 0; i < C.size(); i++)   // i = C.size() - 1时 t 一定小于 10
	{
		t += C[i];
		C[i] = t % 10;
		t /= 10;
	}
	while (C.size() > 1 && C.back() == 0) C.pop_back(); // 必须要去前导 0,因为最高位很可能是 0
	return C;
}
int main()
{
	string a, b;
	cin >> a >> b;
	vector<int> A, B;
	for (int i = a.size() - 1; i >= 0; i--) A.push_back(a[i] - '0');
	for (int i = b.size() - 1; i >= 0; i--) B.push_back(b[i] - '0');
	vector<int> C = Mul(A, B);
	for (int i = C.size() - 1; i >= 0; i--) cout << C[i];
	return 0;
}

4、话说大诗人李白,一生好饮。一天,他提着酒壶,从家里出来,酒壶中有酒2斗。他边走边唱:无事街上走,提壶去打酒。逢店加一倍,遇花喝一斗。这一路上,他一共遇到店5次,遇到花10次,已知最后一次遇到的是花,他正好把酒喝光了。 请你计算李白遇到店和花的次序,可以把遇店记为a,遇花记为b。则:babaabbabbabbbb 就是合理的次序。像这样的答案一共有多少呢?请你计算出所有可能方案的个数。
#include <stdio.h>
//jiu表示酒的数量
//hua表示遇见花的次数
//dian表示遇见店的次数
//yujian每次遇见的是店或花  店记为0,遇花记为1
int sum = 0;//表示所有符合题意的组合数量,这里可以等价写为 int sum;
void f(int jiu, int hua, int dian, int yujian)
{
	if (hua + dian == 15)//某种组合结束
	{
		if (jiu == 0 && hua == 10 && dian == 5 && yujian == 1)
			sum++;
	}
	else
	{
		f(jiu - 1, hua + 1, dian + 0, 1); //某次遇见花
		f(jiu * 2, hua + 0, dian + 1, 0); //某次遇见店
	}
}
int main(void)
{
	f(2, 0, 0, 1);
	//最后一个实参表示遇见,因为没有出门,所以这个值不存在,那就随便写
	printf("%d\n", sum);
	return 0;
}

5、某电视台举办了低碳生活大奖赛。题目的计分规则相当奇怪:每位选手需要回答10个问题(其编号为1到10),越后面越有难度。答对的,当前分数翻倍;答错了则扣掉与题号相同的分数(选手必须回答问题,不回答按错误处理)。每位选手都有一个起步的分数为10分。某获胜选手最终得分刚好是100分,如果不让你看比赛过程,你能推断出他(她)哪个题目答对了,哪个题目答错了吗?如果把答对的记为1,答错的记为0,则10个题目的回答情况可以用仅含有1和0的字符串来表示。例如:0010110011 就是可能的情况。你的任务是算出所有可能情况。每个答案占一行。
#include <stdio.h>
int ti[11] = { 0 }; //用来存储每道题的回答情况0或者1,0表示错误,1表示正确
//提醒:数组ti的编号实际用1-10
//score表示当前得分,num是当前第num道题目
void f(int score, int num)
{
	if (num == 11)//10道题目全部做完
	{
		if (score == 100)
		{
			int i = 0;
			for (i = 1; i <= 10; i++)
				printf("%d", ti[i]);
			printf("\n");
		}
	}
	else //10道题目没有做完
	{
		ti[num] = 1; //讨论第num道题目的正确情况
		f(score * 2, num + 1);
		ti[num] = 0; //讨论第num道题目的错误情况
		f(score - num, num + 1);
	}
}
int main(void)
{
	f(10, 1);//从基础分10分开始,从第1题开始
	return 0;
}

6、输入一个十进制数N,将它转换成R进制数输出。在10≤R≤16的情况下,用’A’表示10,用’B’表示11,用’C’表示12,用’D’表示13,用’E’表示14,用’F’表示15。
输入格式:

输入包含两个整数 N(N≤10000)和R(2≤R≤16)。
注意:N有可能是负整数。

输出格式:

输出一行,表示转换后的数。

样例输入:
742035030 16
样例输出:
2C3A8E56
示例代码:
#include <stdio.h>
int main(void)
{
	int t = 0, N = 0, R = 0, i = 0, j = 0;
	char s[1000] = { '\0' };
	scanf("%d%d", &N, &R);
	if (N == 0) printf("0");
	else if (N != 0)
	{
		if (N < 0) printf("-");
		N = N > 0 ? N : -N;
		while (N)
		{
			t = N % R;
			if (t >= 0 && t <= 9)
				s[i] = 48 + t;
			else if (t >= 10 && t <= 15)
				s[i] = 55 + t;
			i++;
			N = N / R;
		}
		for (j = i - 1; j >= 0; j--) printf("%c", s[j]);
	}
	return 0;
}


7、给你一个整数x ,如果x是一个回文整数,返回true;否则,返回false。回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数。例如,121是回文数,而123不是。
示例1:
输入:x = 121
输出:true
示例2:
输入:x = -121
输出:false
解释:从左向右读,-121 。 从右向左读,121- 。因此它不是一个回文数。
示例3:
输入:x = 10
输出:false
解释:从右向左读,01 。因此它不是一个回文数。
代码:
#include <stdio.h>
#include <stdbool.h>
bool isPalindrome(int x)
{
	if (x < 0) return false;
	else if (x == 0) return true;
	else
	{
		int i = 0, j = 0, a[100] = { 0 };
		while (x > 0)
		{
			a[i] = x % 10;
			i++;
			x = x / 10;
		}
		for (j = 0; j <= (i - 1) / 2; j++)
		{
			if (a[j] != a[i - 1 - j]) return false;
		}
		return true;
	}
}
int main(void)
{
	int x = 0;
	printf("Input x: ");
	scanf("%d", &x);
	printf("%d", isPalindrome(x));
	return 0;
}

8、一个正整数,如果交换高低位以后和原数相等,那么称这个数为回文数。比如121,2332 都是回文数,13,4567不是回文数。任意一个正整数,如果其不是回文数,将该数交换高低位以后和原数相加得到一个新的数,如果新数不是回文数,重复这个变换,直到得到一个回文数为止。例如,57变换后得到132(57 + 75),132得到363(132 + 231)),363是一个回文数。曾经有数学家猜想:对于任意正整数,经过有限次上述变换以后,一定能得出一个回文数。至今这个猜想还没有被证明是对的。现在请你通过程序来验证。
输入格式:

输入一行一个正整数n。

输出格式:

输出第一行一个正整数,表示得到一个回文数的最少变换次数。
接下来一行,输出变换过程,相邻的数之间用"—>"连接。输出格式可以参见样例。
保证最后生成的数在int范围内。

样例输入:
349
样例输出:
3
349--->1292--->4213--->7337
示例代码:
#include <stdio.h>
#include <math.h>
int isPalindrome(int x) //如果传入的正整数是回文数则返回1,否则返回0
{
	if (x < 0) return 0;
	else if (x == 0) return 1;	
	else
	{
		int i = 0, j = 0, a[100] = { 0 };
		while (x > 0)
		{
			a[i] = x % 10;
			i++;
			x = x / 10;
		}
		for (j = 0; j <= (i - 1) / 2; j++)
		{
			if (a[j] != a[i - 1 - j]) return 0;
		}
		return 1;
	}
}
int fz(int x) //返回翻转后的正整数
{
	int a[100] = { 0 }, i = 0, y = 0, j = 0;
	while (x > 0)
	{
		a[i] = x % 10;
		i++;
		x = x / 10;
	}
	i--;
	for (j = 0; j <= i; j++)
	{
		y += a[j] * pow(10, i - j);
	}
	return y;
}
int main(void)
{
	int k = 0, i = 0, a[100] = { 0 }, j = 0;
	scanf("%d", &k);
	while (isPalindrome(k) == 0)
	{
		a[i] = k;
		k += fz(k);
		i++;
	}
	printf("%d\n", i);
	for (j = 0; j < i; j++)
	{
		printf("%d--->", a[j]);
	}
	printf("%d", k);
	return 0;
}

9、小华非常喜欢吃布丁。这一天她打算购买原味和抹茶味两种布丁,共n个,之后按照一定顺序将n个布丁全部吃完。然而如果小华连续吃到三个同口味的布丁,她会感到厌腻而无法继续吃。请你帮助小华规划吃布丁的每一种可行的口味顺序,使她能够全部吃完而不产生厌腻感。
输入格式:

输入一个正整数n,表示布丁的数量。

输出格式:

每行输出一个由’0’和’1’组成的字符串,表示一种可行的吃布丁的顺序。其中0表示原味,1表示抹茶味。 请将可行的每种方案按字典序升序输入。

样例输入:
3
样例输出:
001
010
011
100
101
110
数据范围:

对于100%的数据,保证1≤n≤20;

示例代码:
#include <iostream>
using namespace std;
void f(int j, int n, int* a)
{
	if (j == n) //如果吃的布丁的个数达到了n个,这时就代表一种情况结束了
	{
		int flag = 0;
		for (int i = 0; i <= n - 3; i++)
		{	//遍历该情况,如果存在连续三个相同的布丁,则这种情况flag取值变为1,并且不输出这种情况
			if (a[i] == a[i + 1] && a[i] == a[i + 2] && a[i + 1] == a[i + 2])
				flag = 1;
		}
		if (flag == 0) //如果flag取值依然为0,就代表这种情况符合要求,可以输出
		{
			for (int i = 0; i < n; i++)
			{
				cout << a[i];
			}
			cout << endl;
		}
	}
	else
	{
		a[j] = 0; //讨论第j个布丁是原味的情况
		f(j + 1, n, a); //先讨论0的情况,再讨论1的情况是为了按照字典序输出
		a[j] = 1; //讨论第j个布丁是抹茶味的情况
		f(j + 1, n, a);
	}
}
int main()
{
	int n = 0;
	cin >> n;
	int* p = new int[n];
	f(0, n, p); //初始情况:吃了0个布丁,还有n个,数组p用来表示吃的情况
	delete[] p;
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

aabyte

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值