LOJ P10024 质数方阵 题解

每日一题 day64 打卡

Analysis

这道题一看应该是搜索,因为方阵是5 ( imes) 5固定的。

显然,枚举方阵每一位比直接枚举每一行要好很多,但还是要剪枝。

剪枝一:

因为我们知道(1,1)且每一位上数的和,所以我们可以确定出一个不必枚举25次之多的枚举方案。

下面是我枚举的顺序,只需枚举13位就能推出整个方阵。

![](C:UsersPublicPicturesSample Pictures捕获.PNG)

剪枝二:

如果搜完一行中的4个而推出的第5个,那个数要满足(0 leq x leq 9)

如果第5个是行头,应该满足(x eq 0)

剪枝三:

搜完一行后如果这5个数组成的五位数不是质数,则直接continue

注意:

1.每一行的顺序是题目给定的,比如(1,1),(1,2),(1,3),(1,4),(1,5)

2.要提前用素数筛把五位素数筛好。

3.因为最后输出答案有顺序,所以要全储存起来,最后再排序。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define int long long
#define maxn 100000+10
#define rep(i,s,e) for(register int i=s;i<=e;++i)
#define dwn(i,s,e) for(register int i=s;i>=e;--i)
using namespace std;
inline int read()
{
	int x=0,f=1;
	char c=getchar();
	while(c<'0'||c>'9') {if(c=='-') f=-1; c=getchar();}
	while(c>='0'&&c<='9') {x=x*10+c-'0'; c=getchar();}
	return f*x;
}
void write(int x)
{
	if(x<0) {putchar('-'); x=-x;}
	if(x>9) write(x/10);
	putchar(x%10+'0');
}
int sum,_11,cnt,tot;
int map[6][6];
struct node
{
	int ans_map[6][6];
}ans[10010];
int book[maxn],prime[maxn];
void init()//-1 sign prime
{
    memset(book,-1,sizeof(book));
    rep(i,2,99999)
	{
        if(book[i]==-1) prime[++cnt]=i;
        for(int j=1;j<=cnt&&1ll*i*prime[j]<=99999;++j)
		{
            book[i*prime[j]]=0;
            if(i%prime[j]==0) break;
        }
    }
}
bool cmp(node x,node y)
{
	rep(i,1,5)
		rep(j,1,5)
		{
			if(x.ans_map[i][j]==y.ans_map[i][j]) continue;
			return x.ans_map[i][j]<y.ans_map[i][j];
		}
}
inline int calc(int a,int b,int c,int d,int e)
{
	return a*10000+b*1000+c*100+d*10+e;
}
signed main()
{
	init();
	sum=read();_11=read();
	map[1][1]=_11;
	rep(_22,0,9)
	{
		if(_11+_22>sum) continue;
		map[2][2]=_22;
		rep(_33,0,9)
		{
			if(_11+_22+_33>sum) continue;
			map[3][3]=_33;
			rep(_44,0,9)
			{
				if(_11+_22+_33+_44>sum) continue;
				if(book[calc(_11,_22,_33,_44,sum-(_11+_22+_33+_44))]==0) continue;
				if(sum-(_11+_22+_33+_44)>=10) continue;
				map[4][4]=_44;
				int _55=map[5][5]=sum-(_11+_22+_33+_44);
				rep(_34,0,9)
				{
					if(_44+_34>sum) continue;
					map[3][4]=_34;
					rep(_24,0,9)
					{
						if(_44+_34+_24>sum) continue;
						map[2][4]=_24;
						rep(_14,1,9)
						{
							if(_44+_34+_24+_14>sum) continue;
							if(book[calc(_14,_24,_34,_44,sum-(_44+_34+_24+_14))]==0) continue;
							if(sum-(_44+_34+_24+_14)>=10) continue;
							map[1][4]=_14;
							int _54=map[5][4]=sum-(_44+_34+_24+_14);
							rep(_21,1,9)
							{
								if(_21+_22+_24>sum) continue;
								map[2][1]=_21;
								rep(_23,0,9)
								{
									if(_21+_22+_24+_23>sum) continue;
									if(book[calc(_21,_22,_23,_24,sum-(_21+_22+_24+_23))]==0) continue;
									if(sum-(_21+_22+_24+_23)>=10) continue;
									map[2][3]=_23;
									int _25=map[2][5]=sum-(_21+_22+_24+_23);
									rep(_13,1,9)
									{
										if(_13+_23+_33>sum) continue;
										map[1][3]=_13;
										rep(_43,0,9)
										{
											if(_13+_23+_33+_43>sum) continue;
											if(book[calc(_13,_23,_33,_43,sum-(_13+_23+_33+_43))]==0) continue;
											if(sum-(_13+_23+_33+_43)>=10) continue;
											map[4][3]=_43;
											int _53=map[5][3]=sum-(_13+_23+_33+_43);
											rep(_12,1,9)
											{
												if(_11+_12+_13+_14>sum) continue;
												if(book[calc(_11,_12,_13,_14,sum-(_11+_12+_13+_14))]==0) continue;
												if(sum-(_11+_12+_13+_14)==0) continue;
												if(sum-(_11+_12+_13+_14)>=10) continue;
												map[1][2]=_12;
												int _15=map[1][5]=sum-(_11+_12+_13+_14);
												rep(_42,0,9)
												{
													if(_42+_33+_24+_15>sum) continue;
													if(book[calc(sum-(_42+_33+_24+_15),_42,_33,_24,_15)]==0) continue;
													if(sum-(_42+_33+_24+_15)+_53+_54+_55>sum) continue;
													if(book[calc(sum-(_42+_33+_24+_15),sum-(sum-(_42+_33+_24+_15)+_53+_54+_55),_53,_54,_55)]==0) continue;
													if(_12+_22+_42+sum-(sum-(_42+_33+_24+_15)+_53+_54+_55)>sum) continue;
													if(book[calc(_12,_22,sum-(_12+_22+_42+sum-(sum-(_42+_33+_24+_15)+_53+_54+_55)),_42,sum-(sum-(_42+_33+_24+_15)+_53+_54+_55))]==0) continue;
													if(sum-(_42+_33+_24+_15)==0) continue;
													if(sum-(_42+_33+_24+_15)>=10) continue;
													if(sum-(sum-(_42+_33+_24+_15)+_53+_54+_55)>=10) continue;
													if(sum-(_12+_22+_42+sum-(sum-(_42+_33+_24+_15)+_53+_54+_55))>=10) continue;
													map[4][2]=_42;
													int _51=map[5][1]=sum-(_42+_33+_24+_15);
													int _52=map[5][2]=sum-(sum-(_42+_33+_24+_15)+_53+_54+_55);
													int _32=map[3][2]=sum-(_12+_22+_42+sum-(sum-(_42+_33+_24+_15)+_53+_54+_55));
													rep(_31,1,9)
													{
														if(_11+_21+_31+_51>sum) continue;
														if(book[calc(_11,_21,_31,sum-(_11+_21+_31+_51),_51)]==0) continue;
														if(_31+_32+_33+_34>sum) continue;
														if(book[calc(_31,_32,_33,_34,sum-(_31+_32+_33+_34))]==0) continue;
														if(sum-(_11+_21+_31+_51)+_42+_43+_44>sum) continue;
														if(book[calc(sum-(_11+_21+_31+_51),_42,_43,_44,sum-(sum-(_11+_21+_31+_51)+_42+_43+_44))]==0) continue;
														if(sum-(_31+_32+_33+_34)+_15+_25+_55>sum) continue;
														if(book[calc(_15,_25,sum-(_31+_32+_33+_34),sum-(sum-(_31+_32+_33+_34)+_15+_25+_55),_55)]==0) continue;
														if(sum-(sum-(_11+_21+_31+_51)+_42+_43+_44)!=sum-(sum-(_31+_32+_33+_34)+_15+_25+_55)) continue;
														if(sum-(_11+_21+_31+_51)==0) continue;
														if(sum-(_11+_21+_31+_51)>=10) continue;
														if(sum-(_31+_32+_33+_34)>=10) continue;
														if(sum-(sum-(_11+_21+_31+_51)+_42+_43+_44)>=10) continue;
														map[3][1]=_31;
														int _41=map[4][1]=sum-(_11+_21+_31+_51);
														int _35=map[3][5]=sum-(_31+_32+_33+_34);
														int _45=map[4][5]=sum-(sum-(_11+_21+_31+_51)+_42+_43+_44);
														++tot;
														rep(i,1,5)
														{
															rep(j,1,5)
															{
																ans[tot].ans_map[i][j]=map[i][j];
															}
														}
													}
												}
											}
										}
									}
								}
							}
						}
					}
				}
			}
		}
	}
	sort(ans+1,ans+tot+1,cmp);
	rep(i,1,tot)
	{
		rep(h,1,5)
		{
			rep(l,1,5)
			{
				write(ans[i].ans_map[h][l]);
			}
			putchar('
');
		}
		if(i!=tot) putchar('
');
	}
	return 0;
}

如有失误请各位大佬斧正(反正我不认识斧正是什么意思)

原文地址:https://www.cnblogs.com/handsome-zyc/p/12134328.html