1.简单的全排列问题:
题目:输入一个字符串,打印出该字符串中字符的所有排列。例如输入字符串abc,则打印出由字符a、b、c所能排列出来的所有字符串abc、acb、bac、bca、cab、cba。
2.相关题目:
题目1:输入一个含有8个数组的数组,判断有没有可能把这8个数字分别放到正方体的8个定点上,使得正方体上三组相对的面上的4个顶点的和都相等。如图所示:(其实图只是个幌子,坏的很,本来不考虑这个图也许还能和组合联系在一起)
这相当于先得到a1,a2,a3,a4,a5,a6,a7和a8这8个数字的所有排列,然后判断有没有某一个的裴烈符合题目给定的条件,即a1+a2+a3+a4 = a5+a6+a7+a8, a1+a3+a5+a7 = a2+a4+a6+a8, 并且a1+a2+a5+a6 = a3+a4+a7+a8。
也就是说要在全排列中找到一组以某个定点出发组成的三组相对面的每四个定点的和相等的情况,就得到了符合要求的组合,如果全排列结束也没有找到符合要求的结果,那么这组数字就是不符合题目要求的。
接下来分析代码流程:
1.确定函数及参数:还是排列问题就叫Permutation吧,进去的时候应该会有数组和数组元素个数(int* a, int n),返回值的话可以是个bool类型的值。
2.函数内部设计1:关于循环过程:就是求一个数组的元素的全排列,当然这其中如果在求的过程中已经得到了结果为真,就证明有满足条件的组合存在,就不需要继续搜索了。
3.函数内部设计2:关于停止条件:如果搜索到了最后一个元素位置,也就是一个全排列已经产生:即从pBegin到a的起始位置,就需要判断3对相对的4个顶点的和是否满足条件,如果每组对应相等,那么就将查找的结果改为true,也就是说,需要一个全局的变量,当然main里的临时变量作为参数传递也是可以的。
然后就可以书写代码了,感觉我的Fenix应该是最详细的了,那伦家要申请一个赞,灰常感谢Thanks♪(・ω・)ノ:
#include <iostream>
using namespace std;
bool result = false;
void Permutation(int* a, int pBegin, int n)
{
if(pBegin == n)
{
if((a[0] + a[1] + a[2] + a[3] == a[4] + a[5] + a[6] + a[7])
&& (a[0] + a[2] + a[6] + a[7] == a[1] + a[3] + a[4] + a[5])
&& (a[0] + a[1] + a[4] + a[5] == a[2] + a[3] + a[6] + a[7]))
{
result = true;
}
return ;
}
for(int i = pBegin; i != n; i++)
{
if(!result)
{
int temp = a[i];
a[i] = a[pBegin];
a[pBegin] = temp;
Permutation(a, pBegin + 1, n);
temp = a[pBegin];
a[pBegin] = a[i];
a[i] = temp;
}
}
}
void Permutation(int* a, int n)
{
if(n == 0)
{
return ;
}
Permutation(a, 0, n);
cout<<result<<endl;
}
int main()
{
int a[] = {2,3,2,2,2,2,2,2};
int n = sizeof(a) / sizeof(a[0]);
Permutation(a,n);
return 0;
}
题目2:8皇后问题
题目:在 8 × 8 的国际象棋上摆放8个皇后,使其不能相互共计,即任意两个皇后不得处在同一行、同一列或者同一对角线上。请问总共有多少种符合条件的摆法?
分析:由于 8 个皇后的任意两个不能处在同一行,那么可定是每个皇后占据一行。于是我们可以定义一个数组ColumnIndex[8],数组中第 i 个数字表示位于第i行的皇后的列号,即 index 代表行号,内容表示列号。先把ColumnIndex的8个数字分别用0 ~ 7 初始化,接下来就是对数组ColumnIndex的 8 个数组分别用不同的数字初始化数组,所以,任意两个皇后肯定不同列。我们只需判断每一个排列对应的8个皇后是不是在同一对角线上,也就是对于数组的两个下标 i 和 j ,是不是满足 i - j == ColumnIndex[i] - ColumnIndex[j] 或者 j - i == ColumnIndex[i] - ColumnIndex[j]。
其实和上题基本相似,但是递归结束后的条件有所变化。