今天在做一道题,结果答案始终不对,思路虽然有点笨吧,但是方法一定是没有问题的。
经过一系列的排除,发现是next_permutation()函数的问题。
问题描述
http://oj.ecustacm.cn/problem.php?id=1301
做这道题的时候,一看不就是一个全排列么?。
用next_permutation()函数就完了
#include<cstdio>
#include<algorithm>
#include<cmath>
#define ll long long
using namespace std;
int a[8]={
2,3,5,8,1,4,6,7};
int main(void)
{
int n=0;
ll sum1,sum2;
do
{
bool flag1=false;
bool flag2=false;
bool flag3=false;
bool flag4=false;
sum1=pow(a[0]*10+a[1],2)+pow(a[2]*10+a[3],2)+pow(a[4]*10+a[5],2)+pow(a[6]*10+a[7],2);
sum2=pow(a[0]+a[1]*10,2)+pow(a[2]+a[3]*10,2)+pow(a[4]+a[5]*10,2)+pow(a[6]+a[7]*10,2);
if(a[0]==8||a[2]==8||a[4]==8||a[6]==8)
flag1=true;
if(a[0]==5||a[2]==5||a[4]==5||a[6]==5)
flag2=true;
if(a[0]==3||a[2]==3||a[4]==3||a[6]==3)
flag3=true;
if(a[0]==2||a[2]==2||a[4]==2||a[6]==2)
flag4=true;
if(flag1&&flag2&&flag3&&flag4)
{
if(sum1==sum2)
{
n++;
}
}
}while(next_permutation(a,a+8));
printf("%d %d\n",n,n/24);
return 0;
}
正确的答案应该是 576 24
但是运行的结果却不尽人意,我很好奇为啥?
解决
经过我一系列的排除,我觉的数组的数据初始排列应该有问题。
经过我的一修改。奇妙的好了。
虽然结果正确了,但是我不禁陷入了沉思。
为啥啊?
我又翻书看一下对于next_permutation()的描述。顿时大悟。
原来next_permutation()是按字典序依次排列的,当排列到最大的值是就会返回false.
之前的我用习惯了,忘了最初的概念,当时也没深究,反正用它就是算全排列的,于是造成了做题种出现了错误。
猜想
既然又对next_permutation()函数加深了了解。
那么我们就来实践一下。
猜想:
根据定义next_permutation()函数是按字典序依次排列的,排列到最大停止。
那么如果刚开始的数据的字典序就是最大的,那么应该就只会运行一次,即初始的值。
由上图可以看到我们的猜想是正确的。
总结
next_permutation()函数是按字典序排列的函数。它与初始的数组的值是息息相关的。
不要以为随便一个数组,用next_permutation()函数就可以得到全排列。
要时刻的记住里面的特性。
为了保险起见。在使用前可以先排序数组。再用next_permutation()。
下面是另一位博主写的关于next_permutation的另一个大坑,写的很不错。
我这里就不造轮子了。
C++中全排列函数next_permutation的一个大坑