前几天在微博上看到这个所谓的神题,然后就想着来算算
http://t.qq.com/p/t/487008033132809/14?&#p=2&select=1&time=1432732148&mid=466699120015199&apiType=14&format=1
全排列算法部分抄自:
http://blog.csdn.net/yangliuy/article/details/7555518
如果假设题目中填入的数字不允许重复,那么只要找到
list[0]+(13*list[1])/list[2]+list[3]+12*list[4]-list[5]-11+(list[6]*list[7])/list[8]-10=66的解即可。
然后难点就在于,如何确定这个list。
我先想到的是类似于四皇后的解法,也就是生成一个矩阵
1 1 1 1 1 1 1 1 1 1
2 2 2 2 2 2 2 2 2 2。。。。
然后每列选取一个,然后每一列都不重复即可。。。但是后面突然想到,这事儿没这么复杂,完全可以初始化一个数组
list[]={1,2,3,4,5,6,7,8,9};
然后求这个数组的全排列即可。然后就得到了下面的代码:
#include<iostream>
using namespace std;
//n用于记录解空间总数
int n=0;
void swap(int *a, int *b){
int m;
m = *a;
*a = *b;
*b = m;
}
void perm(int list[], int k, int m)
{
int i;
if(k > m)
{ int sum=0;
//这里是为了排除计算除法时导致的精度丢失的问题,只取能够整除的数据
if((((13*list[1])%list[2])==0)&&((list[6]*list[7])%list[8]==0))
sum=list[0]+(13*list[1])/list[2]+list[3]+12*list[4]-list[5]-11+(list[6]*list[7])/list[8]-10;
if(sum==66) {
for(i = 0; i <= m; i++)
cout<<list[i]<<" ";
cout<<endl;
n++;
}
}
else
{
for(i = k; i <= m; i++)
{
//传说这是全排列的核心,但是我没看懂。。。orz
swap(&list[k], &list[i]);
perm(list, k + 1, m);
swap(&list[k], &list[i]);
}
}
}
int main()
{
int list[] = {1,2,3,4,5,6,7,8,9};
perm(list, 0, 8);
cout<<"total: "<<n<<endl;
return 0;
}
计算结果:
3 2 1 5 4 7 8 9 6
3 2 1 5 4 7 9 8 6
5 2 1 3 4 7 8 9 6
5 2 1 3 4 7 9 8 6
5 3 1 7 2 6 8 9 4
5 3 1 7 2 6 9 8 4
5 4 1 9 2 7 8 3 6
5 4 1 9 2 7 3 8 6
5 9 3 6 2 1 7 8 4
5 9 3 6 2 1 8 7 4
6 3 1 9 2 5 7 8 4
6 3 1 9 2 5 8 7 4
6 9 3 5 2 1 7 8 4
6 9 3 5 2 1 8 7 4
7 3 1 5 2 6 8 9 4
7 3 1 5 2 6 9 8 4
9 3 1 6 2 5 7 8 4
9 3 1 6 2 5 8 7 4
9 4 1 5 2 7 8 3 6
9 4 1 5 2 7 3 8 6
total: 20
Process exited after 3.832 seconds with return value 0
纯新手,欢迎指正^_^