nyoj-488 素数环 +nyoj -32 组合数 (搜索)



数环


时间限制:1000 ms  |  内存限制:65535 KB 


难度:2


描述 
有一个整数n,把从1到n的数字无重复的排列成环,且使每相邻两个数(包括首尾)的和都为素数,称为素数环。


为了简便起见,我们规定每个素数环都从1开始。例如,下图就是6的一个素数环。


输入有多组测试数据,每组输入一个n(0<n<20),n=0表示输入结束。输出每组第一行输出对应的Case序号,从1开始。
 如果存在满足题意叙述的素数环,从小到大输出。

 否则输出No Answer。

样例输入

6

8
3
0

样例输出

Case 1:

1 4 3 2 5 6
1 6 5 2 3 4
Case 2:
1 2 3 8 5 6 7 4
1 2 5 8 3 4 7 6
1 4 7 6 5 8 3 2
1 6 7 4 3 8 5 2
Case 3:

No Answer


dfs

#include<map>
#include<set>
#include<queue>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f
#define ll long long
#define maxn 13005
using namespace std;
int n;
int a[maxn];
int b[maxn];
int vis[maxn];
int flag;
queue<int>q;
void dfs(int y)
{
    if(y==n)
    {
        b[0]=1;
        b[n]=1;
        for(int i=0; i<n; i++)
        {
            if(a[b[i]+b[i+1]]!=0)
                return ;
        }
        printf("1");
        for(int i=1; i<n; i++)
            printf(" %d",b[i]);
        cout<<endl;
        flag=1;
        return ;
    }
    for(int i=2; i<=n; i++)
    {
        if(vis[i]==0&&a[b[y-1]+i]==0)
        {
            vis[i]=1;
            b[y]=i;
            dfs(y+1);
            vis[i]=0;
        }
    }
    return ;
}
int main()
{
    a[0]=1;
    a[1]=1;
    for(int i=2; i<50; i++)
    {
        if(a[i]==0)
        {
            for(int j=2*i; j<100; j+=i)
                a[j]=1;
        }
    }
    int t=0;
    while(~scanf("%d",&n)&&n)
    {
        memset(vis,0,sizeof(vis));
        memset(b,0,sizeof(b));
        flag=0;
        b[0]=1;
        b[n]=1;
        t++;
        printf("Case %d:\n",t);
        if(n==1)
        {
            cout<<1<<endl;
            continue;
        }
        if(n%2==1)
        {
            cout<<"No Answer"<<endl;
            continue;
        }

        dfs(1);
        if(flag==0)
            cout<<"No Answer"<<endl;
    }
}


组合数

时间限制:3000 ms  |  内存限制:65535 KB
难度:3
描述
找出从自然数1、2、... 、n(0<n<10)中任取r(0<r<=n)个数的所有组合。
输入
输入n、r。
输出
按特定顺序输出所有组合。
特定顺序:每一个组合中的值从大到小排列,组合之间按逆字典序排列。
样例输入
5 3
样例输出
543
542
541
532
531
521
432
431
421
321
#include<map>
#include<set>
#include<queue>
#include<math.h>
#include<vector>
#include<string>
#include<stdio.h>
#include<iostream>
#include<string.h>
#include<algorithm>
#define inf 0x3f3f3f
#define ll long long
#define maxn 50
using namespace std;
int n,r,l;
map<string,int>q;
int vis[maxn];
int b[maxn];
int a[maxn];
string s;
struct node
{
    string s;
} ss[maxn*maxn*maxn];
bool cmp(node op,node opp)
{
    return op.s>opp.s;
}
void dfs(int x)
{
    if(x==r)
    {
        memcpy(a,b,sizeof(a));
        sort(a,a+r);
        for(int i=r-1;i>=0;i--)
        {
            s+=(a[i]+'0');
        }
        if(q[s]==0)
        {
            ss[l].s=s;
            l++;
            q[s]=1;
        }
        s="";
        return;
    }
    for(int i=1; i<=n; i++)
    {
        if(vis[i]==0)
        {
            vis[i]=1;
            b[x]=i;
            dfs(x+1);
            vis[i]=0;
        }
    }
    return ;
}
int main()
{
    while(~scanf("%d%d",&n,&r))
    {
        l=0;
        memset(vis,0,sizeof(vis));
        memset(b,0,sizeof(b));
        memset(a,0,sizeof(a));
        q.clear();
        dfs(0);
        sort(ss,ss+l,cmp);
        for(int i=0; i<l; i++)
            cout<<ss[i].s<<endl;
    }
}
wokenengshigeshazi



posted @ 2018-01-09 20:10  _大美  阅读(124)  评论(0编辑  收藏  举报