复试机试【绪论+第一章】:枚举问题+模拟问题

序论

01 a+b

#define _CRT_SECURE_NO_WARNINGS
//这里是为了防止报错 微软认为scanf不安全

#include 
//引入io操作 注意io语法
/*
	它的作用是包含标准输入输出头文件
	(Standard Input-Output Header)
	这个头文件包含了C语言标准库中提供的输入输出函数的声明
	例如 printf() 和 scanf()
*/

using namespace std;

int main() {
	int a,b;

	//接收用户输入的语法
	scanf("%d%d",&a,&b);

	//输出数据的语法
	printf("%d\n", a + b);
	return 0;
}

一章 枚举问题

概念

列出问题所有可能的情况 一个一个去试验是否满足条件

也叫暴力法

解决任何问题第一反应的做法

但是过于暴力 会消耗额外的时间 可能导致程序超时

01 abc问题

描述

设a、b、c均是0到9之间的数字,abc、bcc是两个三位数,且有:abc+bcc=532。求满足条件的所有a、b、c的值。

输出描述

请输出所有满足题目条件的a、b、c的值。 a、b、c之间用空格隔开。 每个输出占一行。

解答

#include //引入头文件
using namespace std;//引入命名空间

int main() {

	/*
		题目要求

		设a、b、c均是0到9之间的数字
		abc、bcc是两个三位数
		且有:abc+bcc=532
		求满足条件的所有a、b、c的值
	*/

	/*
		abc的取值分别为0-9
		只需遍历每一种情况便可
		所以使用三重for循环 逐个检验便可
	*/

	/*
		变量命名规范
		题目要求什么 就用什么
		对于自定义变量 尽量以【单词】作为名字
	*/
	int a, b, c;

	//确定次数的循环 用for循环

	for (a = 0; a <= 9; a++) {
		//循环使用的规范
		//不要省略任何一个花括号
		for (b = 0; b <= 9; b++) {
			for (c = 0; c <= 9; c++) {
				//看abc的值是否满足
				if ((100 * a + 10 * b + c) + (100 * b + 10 * c + c) == 532) {
					printf("%d %d %d\n", a, b, c);
					/*
					printf 是一个标准库函数,用于格式化输出
					"%d %d %d\n" 是格式字符串
					%d 是一个占位符 表示一个整数
					\n 是一个换行符 默认输出后都要加换行符\n
					a, b, c 是要输出的整数变量
					*/
				}
			}
		}
	}
    
	return 0;
}

报错 编译错误

C表明是编译错误

cpp(30,2)表明是第30行出现错误

编译错误只需要根据提示来解决即可

【注意】解决错误时 优先关注第一个错误 因为后面的错误可能是有第一个导致的

报错 链接错误

【编译】.cpp文件编译成.o文件

【链接】将多个.o文件 链接成一个.exe文件

error LNK2019 说明是链接错误 往往是函数名写错了 比如main()写错了

链接错误不知道具体错误在哪一行

报错 运行错误

编译没有错误

链接也没有错误

可以运行 但是结果不符合预期

要使用单步调试 打断点

最好的做法时 写一个部分的功能就测试一下

02 反序数

描述

设N是一个四位数,它的9倍恰好是其反序数(例如:1234的反序数是4321)
求N的值

输出描述

输出题目要求的四位数,如果结果有多组,则每组结果之间以回车隔开。

解答

#include 
using namespace std;

//将要重复使用的内容写成一个函数
int Reverse(int n) {
	//传入数字n
	//实现逆序数操作
	int reverse = 0;//用于保存翻转之后的数字
	int remain;//用于保存余下的未被反转的数字
	while (n > 0) {
		remain = n % 10;//取得n的个位数字
		n = n / 10;//使得n整体右移
		reverse = reverse * 10 + remain;//reverse先左移 再加上个位
	}
	//返回n的逆序数
	return reverse;
}

int main() {

	for (int i = 1000; i <= 9999; i++) {
		if (i * 9 == Reverse(i)) {
			printf("%d", i);
		}
	}
	return 0;
}

一章 模拟问题

概念

看图说话 根据题目的规则和要求 转换成代码得到结果

简单模拟 基本上是签到题

图案打印 涉及到字符串 二维数组

时间日期 关于年月日

复杂模拟 比较麻烦的数据结构 二叉树 图 等等

01 xxx定律

描述

对于一个数n,如果是偶数,就把n砍掉一半;如果是奇数,把n变成 3*n+ 1后砍掉一半,直到该数变为1为止。 请计算需要经过几步才能将n变到1,具体可见样例。

输入描述

测试包含多个用例,每个用例包含一个整数n。(1<=n<=10000)

输出描述

对于每组测试用例请输出一个数,表示需要经过的步数,每组输出占一行。

字符串相关知识

C风格字符串 是靠字符数组实现的

char str[100];
//这就是一个100个字节的字符数组 但并不是全部用来存放字符

02 打印菱形

描述

打印一个由数字 0∼n 构成的菱形。

其中 n 位于正中心,数字靠近边缘时逐个递减,直至为 00。

例如,当 n=5时,图形如下所示:

          0
        0 1 0
      0 1 2 1 0
    0 1 2 3 2 1 0
  0 1 2 3 4 3 2 1 0
0 1 2 3 4 5 4 3 2 1 0
  0 1 2 3 4 3 2 1 0
    0 1 2 3 2 1 0
      0 1 2 1 0
        0 1 0
          0

给定 n请你打印相应菱形

输入格式

一个整数 n

输出格式

输出相应菱形

解答

自己先打印两行试试看 有什么规律

#define _CRT_SECURE_NO_WARNINGS
#include
#include//引入字符串的头文件
using namespace std;
int main() {
	char str[1000] = { 0 };
	int i;
	for (i = 0; i < 10; i++) {
		str[i] = ' ';//前10个都填充空格
	}


	//结束for循环后 i为10
	str[i] = '0';//第11个位置填充为字符0
	printf("%s\n", str);



	//数组全部清空
	memset(str, 0, 1000);
	/*
	用于将一块内存区域设置为特定的值

	将str这个内存地址开始的1000个字节都设置为0
	memset 是一个标准库函数,用于设置内存区域的值
	str 是你要操作的内存区域的起始地址
	0 是你要设置的值
	1000 是你要设置的字节数
	*/



	for (i = 0; i < 8; i++) {
		str[i] = ' ';//前8个都填充空格
	}


	for (int j = 0; j <= 1; j++) {
		str[i] = '0'+j;
		//字符的本质是ASCII码值 
		//字符加上整型 表示ASCII码值向后移多少
		str[i + 1] = ' ';//打印数字后 还要额外打印一个空格
		i = i + 2;
	}

	str[i] = '0'; 
	printf("%s\n", str);

	return 0;
}

用列表格的方式 确定循环时的数字关系

#define _CRT_SECURE_NO_WARNINGS
#include
#include//引入字符串的头文件
using namespace std;
int main() {
	char str[1000] = { 0 };
	//数组所占的内存尽可能大 防止不够用
	int n;
	scanf("%d", &n);
	/*
		%f:用于读取浮点数。
		%c:用于读取字符。
		%s:用于读取字符串。
		%u:用于读取无符号整数。
		%o:用于读取八进制数。
		%x:用于读取十六进制数。
		%e:用于读取科学记数法的浮点数。
		%g:用于读取合适的浮点数,根据输入选择 %f 或 %e。	
	*/
	int i = 0;//行号



	//上半部分内容------------------
	for (i = 0; i <= n; i++) {
		int j = 0;
		
		//清空数组
		memset(str, 0, 1000);
		
		//填充空格
		for (j = 0; j < 2 * n - 2 * i; j++) {
			str[j] = ' ';
		}

		//递增填充
		for (int k = 0; k <= i; k++) {
			str[j] = '0' + k;
			str[j + 1] = ' ';//每填一个数字 后面跟一个空格
			j = j + 2;
		}

		//递减填充
		for (int k = i - 1; k >= 0; k--) {
			str[j] = '0' + k;
			str[j + 1] = ' ';
			j = j + 2;
		}
		//以上 i行字符串全部搞定 下面直接输出一整行
		printf("%s\n", str);
	}
	//-----------------------------------



	
	//下半部分内容------------------
	for (i = n+1; i <= 2*n; i++) {
		int j = 0;

		//清空数组
		memset(str, 0, 1000);

		//填充空格
		for (j = 0; j < 2 * i - 2 * n; j++) {
			str[j] = ' ';
		}

		//递增填充
		for (int k = 0; k <= 2*n-i; k++) {
			str[j] = '0' + k;
			str[j + 1] = ' ';//每填一个数字 后面跟一个空格
			j = j + 2;
		}

		//递减填充
		for (int k = 2*n-i - 1; k >= 0; k--) {
			str[j] = '0' + k;
			str[j + 1] = ' ';
			j = j + 2;
		}
		//以上 i行字符串全部搞定 下面直接输出一整行
		printf("%s\n", str);
	}
	//-----------------------------------






	return 0;
}

图案问题总结

将图案分解成字符串 字符串分解成字符的组合

列表 找元素 数量 行号 列号 之间的关系

从表格中提取规律

写代码

缺陷:只能按照行分解

改进:可以用二维数组

#define _CRT_SECURE_NO_WARNINGS
#include
#include//引入字符串的头文件
using namespace std;
int main() {
	char arr[100][100] = { 0 };
	//= { 0 }: 这是对数组的初始化。这里,所有的元素都被初始化为0。
	
	int n;
	scanf("%d", &n);
	int i = 0;//行号


	//上半部分内容------------------
	for (i = 0; i <= n; i++) {
		int j = 0;
		
		
		//填充空格
		for (j = 0; j < 2 * n - 2 * i; j++) {
			arr[i][j] = ' ';
		}

		//递增填充
		for (int k = 0; k <= i; k++) {
			arr[i][j] = '0' + k;
			arr[i][j+1] = ' ';//每填一个数字 后面跟一个空格
			j = j + 2;
		}

		//递减填充
		for (int k = i - 1; k >= 0; k--) {
			arr[i][j] = '0' + k;
			arr[i][j+1] = ' ';
			j = j + 2;
		}
		//以上 i行字符串全部搞定 下面直接输出一整行
		
	}
	//-----------------------------------



	
	//下半部分内容------------------
	for (i = n+1; i <= 2*n; i++) {
		int j = 0;

		//填充空格
		for (j = 0; j < 2 * i - 2 * n; j++) {
			arr[i][j] = ' ';
		}

		//递增填充
		for (int k = 0; k <= 2*n-i; k++) {
			arr[i][j] = '0' + k;
			arr[i][j+1] = ' ';//每填一个数字 后面跟一个空格
			j = j + 2;
		}

		//递减填充
		for (int k = 2*n-i - 1; k >= 0; k--) {
			arr[i][j] = '0' + k;
			arr[i][j+1] = ' ';
			j = j + 2;
		}

	}
	//-----------------------------------

	//打印二维数组

	for (int i = 0; i < 2 * n + 1; i++) {
		printf("%s\n", arr[i]);//视为打印字符串 字符数组就是字符串
	}



	return 0;
}

遇见打印问题 优先使用二维数组

03 叠筐问题

描述

需要的时候,就把一个个大小差一圈的筐叠上去,使得从上往下看时,边筐花色交错。这个工作现在要让计算机来完成,得看你的了。

输入格式

输入是一个个的三元组,分别是,外筐尺寸n(n为满足0

输出格式

输出叠在一起的筐图案,中心花色与外筐花色字符从内层起交错相叠,多筐相叠时,最外筐的角总是被打磨掉。叠筐与叠筐之间应有一行间隔。

输入示例

11 B A
5 @ W

输出示例

 AAAAAAAAA 
ABBBBBBBBBA
ABAAAAAAABA
ABABBBBBABA
ABABAAABABA
ABABABABABA
ABABAAABABA
ABABBBBBABA
ABAAAAAAABA
ABBBBBBBBBA
 AAAAAAAAA 

 @@@ 
@WWW@
@W@W@
@WWW@
 @@@ 

思考过程

优先想到用二维数组 一层一层地看 不要一下子看全部

然后列表格分析规律 先分析确定的n=10 再分析变化的n

解答

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 

using namespace std;
int main() {
	int n;
	char in, out;

	//11 b a
	//如果是%d %lf 那么scanf会忽略空白
	//%c不忽略空白
	//所以中间要写个空格


	char pattern[100][100] = { 0 };

	while (scanf("%d %c %c", &n, &in, &out) != EOF) {
		int layer;//层级

		//每一次读取输入之后 都要清空数组
		memset(pattern, 0, 10000);

		char current = in;//当前层级的花色

		for (layer = 0; layer <= n / 2; layer++) {
			//四个顶点的下面
			//n/2-layer,n/2-layer 左上
			//n/2-layer,n/2+layer 右上
			//n/2+layer,n/2-layer 左下
			//n/2+layer,n/2+layer 右下


			//依次填充四个边

			//填充上面的变 x不变 y变 
			for (int x = n / 2 - layer, y = n / 2 - layer; y <= n / 2 + layer; y++) {
				pattern[x][y] = current;
			}

			//填充下面的变 x不变 y变
			for (int x = n / 2 + layer, y = n / 2 - layer; y <= n / 2 + layer; y++) {
				pattern[x][y] = current;
			}

			//填充左边的变 x变 y不变
			for (int x = n / 2 - layer, y = n / 2 - layer; x <= n / 2 + layer;x++) {
				pattern[x][y] = current;
			}

			//填充右边的变 x变 y不变
			for (int x = n / 2 - layer, y = n / 2 + layer; x <= n / 2 + layer; x++) {
				pattern[x][y] = current;
			}


			//填一圈换一个颜色
			if (in == current) {
				current = out;
			}
			else {
				current = in;
			}


			//四个角挖空格
			if (n != 1) {
				pattern[0][0] = ' ';
				pattern[0][n-1] = ' ';
				pattern[n-1][0] = ' ';
				pattern[n-1][n-1] = ' ';

			}
		}
		//打印二维数组
		for (int i = 0; i < n; i++) {
			printf("%s\n", pattern[i]);
		}

		printf("\n");
	}
	return 0;
}

;
}

		//填充左边的变 x变 y不变
		for (int x = n / 2 - layer, y = n / 2 - layer; x <= n / 2 + layer;x++) {
			pattern[x][y] = current;
		}

		//填充右边的变 x变 y不变
		for (int x = n / 2 - layer, y = n / 2 + layer; x <= n / 2 + layer; x++) {
			pattern[x][y] = current;
		}


		//填一圈换一个颜色
		if (in == current) {
			current = out;
		}
		else {
			current = in;
		}


		//四个角挖空格
		if (n != 1) {
			pattern[0][0] = ' ';
			pattern[0][n-1] = ' ';
			pattern[n-1][0] = ' ';
			pattern[n-1][n-1] = ' ';

		}
	}
	//打印二维数组
	for (int i = 0; i < n; i++) {
		printf("%s\n", pattern[i]);
	}

	printf("\n");
}
return 0;

}


你可能感兴趣的:(笔记,算法,c语言,c++)