使用next_permutation()的坑,你中招了么?

今天在做一道题,结果答案始终不对,思路虽然有点笨吧,但是方法一定是没有问题的。
经过一系列的排除,发现是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的一个大坑

猜你喜欢

转载自blog.csdn.net/qq_46527915/article/details/115276567