問題の説明
リングは、図に示すようにn個の円で構成されています。自然数
1、2、…、nを各円に別々に入れ、2つの
隣接する円の数の合計が素数になるはずです。
注:最初の円の数は常に1である必要があります。
入力
n(0 <n <20)。
出力
出力フォーマットを以下のサンプルとして示します。
各行は、
1から時計回りおよび反時計回りに始まるリング内の一連の円番号を表します。番号の順序は
、上記の要件を満たしている必要があります。ソリューションを辞書式
順序で印刷します。
上記のプロセスを完了するプログラムを作成する必要があります。
各ケースの後に空白行を印刷します。
サンプル入力
6
8
サンプル出力
ケース1:
1 4 3 2 5 6
1 6 5 2 3 4
ケース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
題名:
自然数1、2、...、nを円に入れると、隣接する2つの円の数の合計が素数になります。最初の円の数は常に1でなければなりません。
アイデア:
まず、素数を格納せずに素数のリストを印刷します。素数は0ではなく1としてマークされます。次に、深さ優先検索が実行され、出口の2つの隣接する番号が素数に追加されます。ディープサーチを正直に入力するだけでOKです。
ACコード
#include<stdio.h>
#include<string.h>
void dfs(int cur);
int prime(int x);
int n,a[20],b[41],c[20];
int main()
{
int i;
for(i=2;i<=40;i++)
b[i]=prime(i);//打表
int k=1;
while(scanf("%d",&n)!=EOF)
{
a[0]=1;
printf("Case %d:\n",k++);
if(n%2==0)
{
dfs(1);开始深搜
}
printf("\n");
}
return 0;
}
int prime(int x)
{
int i;
for(i=2;i*i<=x;i++)
if(x%i==0)
{
return 0;
break;
}
return 1;
}
void dfs(int cur)
{
int i;
if(cur==n&&b[a[0]+a[n-1]])
{
for(i=0;i<n-1;i++)
printf("%d ",a[i]);
printf("%d\n",a[n-1]);
}
else
for(i=2;i<=n;i++)
if(!c[i]&&b[i+a[cur-1]])
{
a[cur]=i;
c[i]=1;
dfs(cur+1);
c[i]=0;
}
}