本文源代码地址:click here,欢迎star和fork~~~共同学习~~~~参考资料
目录
注意不要盲目相信以下内容! 不要盲目相信以下内容! 不要盲目相信以下内容! (重要的事情说三遍),虽然以下内容也经过了我的验证,但是我的验证可能有错误的地方,欢迎大家留言告知。希望这篇文章成为你深入探索相关领域的引子和启发,而不是标准答案。
枚举
枚举虽然是我们日常生活中最常用的方法,但实际上这种方法要用的好还是有一定困难。
百钱百鸡问题
问题描述:
共有一百文钱,要求买到100只鸡。其中公鸡5文一只,母鸡3文一只,小鸡1文3只。
关键伪代码如下:
int z = 0;
for (int x = 0; x < 100;x++)
for (int y = 0; y < 100-x; y++)
{
z = 100 - x - y;
if (z % 3 == 0)
{
if (z/3 + 3 * y + 5 * x == 100)
{
x,y,z is the solution;
}
}
}
//只需要简单的进行两层循环即可
熄灯问题
问题描述:5*6的灯泡和按键组成的矩阵,按下按键可以改变自己以及周围四邻域的灯泡的状态(4个角上的按钮改变3盏灯,边上的按钮改变4盏灯,其他按钮改变5盏灯状态)。此时给定一个初始状态,求一个按钮矩阵,使得按下相应按钮可以使所有灯泡熄灭。
在下图中, 左边矩阵中用X标记的按钮表示被按下,
右边的矩阵表示灯状态的改变
输入:
• 第一行是一个正整数N, 表示需要解决的案例数
• 每个案例由5行组成, 每一行包括6个数字
• 这些数字以空格隔开, 可以是0或1
• 0 表示灯的初始状态是熄灭的
• 1 表示灯的初始状态是点亮的
输出:
• 对每个案例, 首先输出一行, 输出字符串 “PUZZLE #m
”, 其中m是该案例的序号
• 接着按照该案例的输入格式输出5行
• 1 表示需要把对应的按钮按下
• 0 表示不需要按对应的按钮
• 每个数字以一个空格隔开
解题思路:
int main(){}
讨厌的青蛙问题
递归
求解:给定一个数组a[N],我们希望构造数组b[N],其中b[i]=a[0]a1…*a[N-1]/a[i]。 下面是完整题目
给定一个数组a[N],我们希望构造数组b[N],其中b[i]=a[0]a1…*a[N-1]/a[i]。在构造过程:
不允许使用除法;
要求O(1)空间复杂度和O(n)时间复杂度;
除遍历计数器与a[N] b[N]外,不可使用新的变量(包括栈临时变量、对空间和全局静态变量等);
请用程序实现并简单描述。
可以在b数组的基础上做两次遍历,先存前缀,再存后缀
int main(){
const int n = 8;
int a[n] = {1,2,3,4,5,6,7,8};
int b[n];
b[n-1] = 1;
for (int i=n-2;i>=0;i–)
b[i] = b[i+1]*a[i+1];
for(int i=1;i<n-1;i++)
{
b[n-1]*=a[i-1];
b[i] *= b[n-1];
}
b[n-1]*=a[n-2];
for (int i=0;i<n;i++)
cout << b[i] << endl;
}
设计一个算法,将数组A(0….n-1)中的元素循环右移k位,假设原数组序列为a0,a1,a2,…..,an-1;移动后的序列为an-k,an-k+1,…,a0,a1,…,an-k-1.
空间复杂度O(1),时间复杂度O(n)
解法:假设原数组序列为abcd1234,右移4位变成1234abcd,可把两段看成两个整体。
右移K位的过程就是把数组的两部分交换一下。
变换过程通过以下步骤完成:
1.逆序排列 abcd: abcd1234 -> dcba1234;
2.逆序排列 1234: dcba1234-> dcba4321;
3.全部逆序 dcba4321->1234abcd。