next_permutation 和 一个不成功的案例
一个失败的案例:(POJ 1009)
题目描述
小翔同学的宿舍WIFI添加了密码,密码每天都会变更。而小翔每天都会给蹭网的同学们提供密码提示。现在请你根据密码提示,编写程序破译密码。 已知密码提示给出了n个整数 a1,a2,…,an,以及一个整数 t(t小于n)。从这n个整数中任选t个相加,可分别得到一系列的和。例如当 n=4,t=3,4 个整数分别为 3,7,12,19 时,可得全部组合的和分别为:
3+7+12=22 3+7+19=29 7+12+19=38 3+12+19=34。 而和为素数的个数即为小翔宿舍WIFI的密码。
例如上例,只有一种的和为素数:3+7+19=29,于是密码即为1。
输入
n , t (1<=n<=20,t<n) a1,a2,…,an (1<=ai<=5000000)
样例输入
样例输出
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<iostream> #include<string.h> #include<algorithm> #include<stdio.h> #include<math.h> using namespace std; long d[25],*head; int i,n,t,sum=0,mark=0,Q; int fun(int ns) { int j,m; m=(int)sqrt(ns); for(j=2;j<=m;j++) { if(!(ns%j)) {return 0;} } return 1; } int permutation() { if(Q<t){cout<<n<<Q<<t<<"$"; return mark;} do { for(i=0;i<t;i++) { sum=sum+d[i]; cout<<d[i]<<"*"; } if(fun(sum)==1) { mark++; } sum=0; }while(next_permutation(d,d+Q)); Q--;cout<<"!"; permutation(); } int main() { freopen("stdin.txt","r",stdin); while(scanf("%d %d",&n,&t)!=EOF) { for(i=0;i<n;i++) { scanf("%ld",&d[i]); } Q=n; cout<<permutation()<<endl; mark=n=t=0; } return 0; //相同时合并,缺少情况 }
next_permutation遇到同次相同序列会合并,用到这道题会出错,要注意用的条件,这道题用DFS即可,这道题撸了三天我也是醉了。
正解:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<stdio.h> 3 #include<math.h> 4 #include<string.h> 5 using namespace std; 6 int i=1,j,sum,num,n,t; 7 long int d[25]; 8 int fun(int n) 9 { 10 int m; 11 m=(int)sqrt(n); 12 for(j=2;j<=m;j++) 13 { 14 if(!(n%j)) 15 {return 0;} 16 } 17 return 1; 18 } 19 20 void dfs(int abc,int i,int sum) 21 { 22 if(abc==t&&fun(sum)) 23 {num++;return;} 24 for(int j=i;j<n;j++) 25 {dfs(abc+1,j+1,sum+d[j]);} 26 } 27 28 int main() 29 { 30 while(scanf("%d%d",&n,&t)!=EOF) 31 { 32 for(int i=0;i<n;i++) 33 scanf("%ld",&d[i]); 34 dfs(0,0,0); 35 cout<<num<<endl; 36 num=sum=0; 37 } 38 return 0; 39 } 40 /************************************************************** 41 Problem: 1009 42 User: 2014217052 43 Language: C++ 44 Result: 正确 45 Time:4 ms 46 Memory:1516 kb 47 ****************************************************************/
几种常见用法:
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
char d[100];
cin>>d;
sort(d,d+strlen(d));
char *first=d;
char *last=d+strlen(d);
do{
cout<<d<<endl;
}while(next_permutation(first,last));
return 0;
}
////////////////////////////////////////////
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int main()
{
char d[100];
cin>>d;
sort(d,d+strlen(d));
char *first=d;
char *last=d+strlen(d);
do{
cout<<d<<endl;
}while(next_permutation(first,last));
return 0;
}
//////////////////////////////////////////
#include<iostream>
#include<string.h>
#include<algorithm>
using namespace std;
int main() {
string dog;
while(cin>>dog&&dog!="@")
{
sort(dog.begin(),dog.end());
while(next_permutation(dog.begin(),dog.end()))
{
cout<<dog<<endl;
}
}
}
///////////////////////////////////////