Fox Ciel is participating in a party in Prime Kingdom. There are n foxes there (include Fox Ciel). The i-th fox is ai years old.
They will have dinner around some round tables. You want to distribute foxes such that:
- Each fox is sitting at some table.
- Each table has at least 3 foxes sitting around it.
- The sum of ages of any two adjacent foxes around each table should be a prime number.
If k foxes f1, f2, ..., fk are sitting around table in clockwise order, then for 1 ≤ i ≤ k - 1: fi and fi + 1 are adjacent, and f1 and fk are also adjacent.
If it is possible to distribute the foxes in the desired manner, find out a way to do that.
The first line contains single integer n (3 ≤ n ≤ 200): the number of foxes in this party.
The second line contains n integers ai (2 ≤ ai ≤ 104).
If it is impossible to do this, output "Impossible".
Otherwise, in the first line output an integer m (): the number of tables.
Then output m lines, each line should start with an integer k -=– the number of foxes around that table, and then k numbers — indices of fox sitting around that table in clockwise order.
If there are several possible arrangements, output any of them.
4 3 4 8 9
1 4 1 2 4 3
5 2 2 2 2 2
Impossible
12 2 3 4 5 6 7 8 9 10 11 12 13
1 12 1 2 3 6 5 12 9 8 7 10 11 4
24 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
3 6 1 2 3 6 5 4 10 7 8 9 12 15 14 13 16 11 10 8 17 18 23 22 19 20 21 24
题意:给你n个值,让你将这n个值围成任意圈,使得每个圈中个数都大于三个并且每个数与它相邻的数的和为素数。
思路:如果和为素数的话,那么必是一个奇数加上一个偶数。所以让0到奇数的f=2,偶数到n+1的f=2,如果奇偶的和为素数时让他们的f=1。
AC代码如下:
#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
struct node
{
int v,flow,next;
}edge[40010];
int n,Prime[20010],num[210],Head[210],d[210],e,desk[210][210],vis[210],INF=1e9,link[210][210];
queue<int> qu;
void add(int u,int v,int f)
{
edge[e].v=v;
edge[e].flow=f;
edge[e].next=Head[u];
Head[u]=e;
e++;
}
void init()
{
int i,j,k;
e=0;
memset(Head,-1,sizeof(Head));
for(i=1;i<=n;i++)
if(num[i]&1)
{
add(0,i,2);
add(i,0,2);
}
else
{
add(i,n+1,2);
add(n+1,i,0);
}
for(i=1;i<=n;i++)
for(j=i+1;j<=n;j++)
if(Prime[num[i]+num[j]]==0)
{
if(num[i]&1)
{
add(i,j,1);
add(j,i,0);
}
else
{
add(j,i,1);
add(i,j,0);
}
}
}
int bfs()
{
int i,j,u,v;
memset(d,-1,sizeof(d));
while(!qu.empty())
qu.pop();
d[0]=0;
qu.push(0);
while(!qu.empty())
{
u=qu.front();
qu.pop();
for(j=Head[u];j!=-1;j=edge[j].next)
if(edge[j].flow>0 && d[edge[j].v]==-1)
{
d[edge[j].v]=d[u]+1;
if(edge[j].v==n+1)
return 1;
qu.push(edge[j].v);
}
}
return 0;
}
int dfs(int u,int f)
{
if(u==n+1 || f==0)
return f;
int ans=0,v,i,j,k;
for(j=Head[u];j!=-1;j=edge[j].next)
if(edge[j].flow>0 && d[edge[j].v]==d[u]+1)
{
k=dfs(edge[j].v,min(edge[j].flow,f));
edge[j].flow-=k;
edge[j^1].flow+=k;
ans+=k;
f-=k;
if(f==0)
break;
}
d[u]=-1;
return ans;
}
int dinic()
{
int ans=0;
while(bfs())
ans+=dfs(0,INF);
return ans;
}
void dfs2(int p,int u)
{
int i,j,k;
for(i=1;i<=n;i++)
if(vis[i]==0 && link[u][i]==1)
{
vis[i]=1;
desk[p][0]++;
desk[p][desk[p][0]]=i;
dfs2(p,i);
}
}
int main()
{
int i,j,k,ans,p;
for(i=2;i<=200;i++)
if(Prime[i]==0)
for(j=i*2;j<=20000;j+=i)
Prime[j]=1;
scanf("%d",&n);
for(i=1;i<=n;i++)
scanf("%d",&num[i]);
init();
ans=dinic();
if(ans!=n)
printf("Impossible\n");
else
{
for(i=1;i<=n;i++)
if(num[i]&1)
for(j=Head[i];j!=-1;j=edge[j].next)
if(edge[j].flow==0)
{
link[i][edge[j].v]=1;
link[edge[j].v][i]=1;
}
p=0;
for(i=1;i<=n;i++)
if(vis[i]==0)
{
vis[i]=1;
p++;
desk[p][0]=1;
desk[p][1]=i;
dfs2(p,i);
}
printf("%d\n",p);
for(i=1;i<=p;i++)
{
printf("%d",desk[i][0]);
for(j=1;j<=desk[i][0];j++)
printf(" %d",desk[i][j]);
printf("\n");
}
}
}