这道题原来用的是next_permutation ,超时,没办法,就改用深搜了。
下面是使用next_permutation的代码:
/**
time: 8.14
author: kaka
content: for hdoj1016
attention:
1.超时未通过
*/
#include <iostream>
#include <algorithm>
using namespace std;
int n;
//输出符合条件的数列
void printNum(int *a)
{
for ( int i = 0; i < n; i++ )
{
cout << a[i]<<" " ;
}
cout <<endl;
}
//判断是不是质数
bool isPrime(int num)
{
for(int i = 2 ; i < num/2; i++)
{
if(num%i==0)return false;
}
return true;
}
//判断每个数列是不是符合规矩
bool isOK(int *a)
{
for ( int i = 0; i<n-1; i++)
{
if(!isPrime(a[i]+a[i+1]))
return false;
}
if(!isPrime(a[n-1]+a[0]))return false;
return true;
}
int number[20];
int main()
{
//cout << "kaka"<<endl;
int t=1;
while(cin>>n)
{
cout << "Case "<<t<<":"<<endl;
for(int i = 1; i <=n; i++)
{
number[i-1]=i;
}
//对每一个利用permutation的数列进行分析
do{
if(isOK(number))
{
printNum(number);
}
}while(next_permutation(number,number+n)&&number[0]==1);
cout <<endl;
t++;
}
}
下面是深搜:
/**
time: 8.14
author: kaka
content: for hdoj1016,利用深搜的版本。
1.本来挺简单的,但有两个问题一直没有找到
2.一个问题是每一行数字列最后不能有空格,否则就是显示错误
3.在递归dfs里,step++,后面加加没有用。这点很不好。
4.还有这种包含递归的怎么找错。首先,是自己推理,然后,进来吧步数输出来
*/
#include<iostream>
using namespace std;
int n;
struct Point
{
int value;
bool flag;
};
Point number[20];
int result[20];
void printNum(int *a)
{
for ( int i = 0; i < n; i++ )
{
cout << a[i] ;
if(i==n-1)
cout <<endl;
else cout << " ";
}
// cout <<endl;
}
bool isPrime(int num)
{
for(int i = 2 ; i < num/2; i++)
{
if(num%i==0)return false;
}
return true;
}
void dfs(int step)
{
if(step==n+1)
{
if(isPrime(result[n-1]+result[0]))
{
printNum(result);
}
return ;
}
for (int i = 1; i < n; i++ )
{
if(number[i].flag&&isPrime(number[i].value+result[step-2]))
{
number[i].flag=false;
result[step-1]=number[i].value;
dfs(step+1);
number[i].flag=true;
}
}
return;
}
int main()
{
int time=0;
while(cin>>n)
{
time++;
cout <<"Case "<<time<<":"<<endl;
for (int i = 0; i < n; i++ )
{
number[i].value=i+1;
number[i].flag=true;
}
number[0].flag=false;
result[0]=1;
dfs(2);
cout <<endl;
}
}
之前还写了一个加入预处理的利用permutation的改进版,但是也时间上还是不行,也一起贴出来
/**
1.预处理没有成功,感觉写的没什么错误,就是运行的时候很长时间没有反应。估计是在计算。
2.不能这么写,因为仔细想了想,是存不了东西的。就是无法把已经确定可以的数列存起来。
3.看3.cpp吧,用深搜
*/
#include <iostream>
#include <algorithm>
using namespace std;
int n;
void printNum(int *a)
{
for ( int i = 0; i < n; i++ )
{
cout << a[i]<<" " ;
}
cout <<endl;
}
bool isPrime(int num)
{
for(int i = 2 ; i < num/2; i++)
{
if(num%i==0)return false;
}
return true;
}
bool isOK(int *a,int n)
{
for ( int i = 0; i<n-1; i++)
{
if(!isPrime(a[i]+a[i+1]))
return false;
}
if(!isPrime(a[n-1]+a[0]))return false;
return true;
}
int number[19][19];
int numberB[1000][19];
int main()
{
//cout << "kaka"<<endl;
for (int i = 0; i < 19; i++)
{
for (int j = 0; j < i+1; j++)
{
number[i][j]=j+1;
}
}
for(int i = 0; i < 19; i++)
{
int t=0;
do{
//cout <<"main: 47: " << number[0]<<endl;
if(isOK(number[i],i+1))
{
//数组之间的拷贝
//numberB[t++]=number[i];
for ( int j = 0; j < i+1;j++)
{
numberB[t][j] = number[i][j];
}
t++;
}
}while(next_permutation(number[i],number[i]+i+1)&&number[i][0]==1);
}
int t1=1;
while(cin>>n)
{
cout << "Case "<<t1<<":"<<endl;
printNum(number[n]);
cout <<endl;
t1++;
}
}