题目:https://vjudge.net/problem/UVA-524

这道题我十个月之前做过,但是当时的代码并不是自己打出来了,对回溯递归之类的也不是很懂。

现在我重新自己手打这道题,却发现了一个小坑点,找了好久才找到。。

ac代码:


注意看第46行的int i=2,一定要加int!!因为之前int定义的是全局变量,所有后续的一些操作会改变i的值,回溯时的vis[i]就不再是对应的进入通过if判断条件时的i。

#include <iostream>
#include <cmath>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <stdlib.h>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <sstream>
#define maxn 35
using namespace std;
typedef long long ll;
int  prime[maxn]={0},vis[maxn],ans[maxn];
int i,j,k,n;
void Prime(int N)
{
    for(i=2;i<=N;i++)
    {
        bool flag=true;
        k=(int)sqrt(i);
        for(j=2;j<=k;j++)
          if(i%j==0)
          {
              prime[i]=0;
              flag=false;
              break;
          }
        if(flag)
            prime[i]=1;
    }
}
void search(int cur)
{
    if(cur==n && prime[ans[n-1]+ans[0]])//输出条件
    {
        printf("%d",ans[0]);
        for(int i=1;i<n;i++)
            printf(" %d",ans[i]);
        printf("\n");
    }
    else
    {
        for(int i=2;i<=n;i++)
        {
            if(!vis[i] && prime[ans[cur-1]+i])//未被拿出且相邻和为素数
            {
                vis[i]=1;
                ans[cur]=i;
                search(cur+1);
                vis[i]=0;
            }
        }
    }
}
int main()
{
    int num=1;
    Prime(35);
    while(scanf("%d",&n)!=EOF)
    {
        if(num>1) printf("\n");
        printf("Case %d:\n",num++);
        memset(vis,0,sizeof(vis));
        ans[0]=1;
        vis[1]=1;
        search(1);
    }
    return 0;
}