毒瘤題解
題目大意:有一個5*5的方陣,給出左上角的一個數以及每一行、每一列、每一斜行的數字和,求所有可能的填數方案並且按照方陣從上往下、從左往右組成的25位數從小到大排序。
(要保證每一行、每一列、每一斜行的五個數從左往右組成的五位數是一個五位質數,有前導0的不算)
tag:深搜
下面讓我們來捋一捋:
1.這是一個填表游戲(貌似廢話)
2.每一行的五個數,其實要去枚舉的最多的只有三個數而已,剩余的一個可以用總和推出來
3.填一個數時,可能要判斷多次,因為填下一個數可能會導致好幾個行或者列被填滿,需要判斷;所以使用某些填表順序的時候可能比較繁瑣,要盡量避開這些詭異的格點。
(Tips:這些東西真的真的一定要避開,要不然填表的時候填着填着自己都會亂掉或是查錯的時候難以查出,曾經修改兩次填表順序,繁瑣的要命)
4.其實要解決的就是一個填表順序的問題
5.填表的起點非常顯然:左斜行,第一行或第一列。
6.填表過程中,若有一段已經被填上了4個數,則可以直接推出來剩下的一個
7.若推剩下這個數的時候,扣掉之后這個數>9或<0,則方案不可行
以下圖片可能有點糊,S表示已知或者推出來的,X表示枚舉出來的
所以下面就要來解決這個問題:
那我們就先從第一斜行填起吧!(所有名字里帶着f1的函數都是)

然后就是第一列(帶f2的)

然后第二行(帶f3的)

接着搞定右斜行(帶f4的)

然后搞定第三行(很繁瑣是不是)(帶f5的)

注意,此時可以把第五列推出來

然后可以把第四行推出來

下面搞定第二列(帶f6的)

然后再搞定第三列(帶f7的)

順便把第一行搞定掉

最后搞定第五行、第四列;
注意!!!這個地方要判斷兩邊,必須要第五行、第四列推出來的那個數一樣以及行、列都滿足其他條件(質數等)才能視為這個方案是OK的,top++;

於是就OK啦!
169行code:
#include<bits/stdc++.h>
using namespace std;
bool prime[100001];
void prim(){
for(register int i=2;i<=sqrt(100000);i++){
if(!prime[i]){
for(register int j=i+i;j<=100000;j+=i)prime[j]=1;
}
}
}
struct data{
int a[6][6];
bool operator <(const data &d)const{
for(register int i=1;i<=5;i++){
for(register int j=1;j<=5;j++){
if(a[i][j]<d.a[i][j])return 1;
else if(a[i][j]>d.a[i][j])return 0;
}
}
return 0;
}
bool operator =(const data &d){
for(register int i=1;i<=5;i++){
for(register int j=1;j<=5;j++){
a[i][j]=d.a[i][j];
}
}
}
}bas[10001];
int sum,s,top=0;
bool check(int a1,int a2,int a3,int a4,int a5){
int num=a1*10000+a2*1000+a3*100+a4*10+a5;
if(num<10000)return 0;
return !prime[num];
}
void f7(){
for(register int i=0;i<=9;i++){
bas[top].a[1][3]=i;
int num=sum-bas[top].a[1][1]-bas[top].a[1][2]-bas[top].a[1][3]-bas[top].a[1][5];
if(num>9||num<0)continue;bas[top].a[1][4]=num;
if(!check(bas[top].a[1][1],bas[top].a[1][2],bas[top].a[1][3],bas[top].a[1][4],bas[top].a[1][5]))continue;
num=sum-bas[top].a[1][3]-bas[top].a[2][3]-bas[top].a[3][3]-bas[top].a[4][3];
if(num>9||num<0)continue;bas[top].a[5][3]=num;
if(!check(bas[top].a[1][3],bas[top].a[2][3],bas[top].a[3][3],bas[top].a[4][3],bas[top].a[5][3]))continue;
num=sum-bas[top].a[5][1]-bas[top].a[5][2]-bas[top].a[5][3]-bas[top].a[5][5];
int num2=sum-bas[top].a[1][4]-bas[top].a[2][4]-bas[top].a[3][4]-bas[top].a[4][4];
if(num>9||num<0||num2!=num)continue;
bas[top].a[5][4]=num;
if(!check(bas[top].a[5][1],bas[top].a[5][2],bas[top].a[5][3],bas[top].a[5][4],bas[top].a[5][5])||!check(bas[top].a[1][4],bas[top].a[2][4],bas[top].a[3][4],bas[top].a[4][4],bas[top].a[5][4]))continue;
top++;bas[top]=bas[top-1];
}
}
void f6(){
for(register int i=0;i<=9;i++){
bas[top].a[1][2]=i;
int num=sum-bas[top].a[1][2]-bas[top].a[2][2]-bas[top].a[3][2]-bas[top].a[4][2];
if(num>9||num<0)continue;bas[top].a[5][2]=num;
if(check(bas[top].a[1][2],bas[top].a[2][2],bas[top].a[3][2],bas[top].a[4][2],bas[top].a[5][2]))f7();
}
}
void f5(){
for(register int i=0;i<=9;i++){
bas[top].a[3][5]=i;
int num=bas[top].a[4][5]=sum-bas[top].a[1][5]-bas[top].a[2][5]-bas[top].a[3][5]-bas[top].a[5][5];
if(num>9||num<0)continue;
if(!check(bas[top].a[1][5],bas[top].a[2][5],bas[top].a[3][5],bas[top].a[4][5],bas[top].a[5][5]))continue;
num=bas[top].a[4][3]=sum-bas[top].a[4][1]-bas[top].a[4][2]-bas[top].a[4][4]-bas[top].a[4][5];
if(num>9||num<0)continue;
if(!check(bas[top].a[4][1],bas[top].a[4][2],bas[top].a[4][3],bas[top].a[4][4],bas[top].a[4][5]))continue;
num=sum-bas[top].a[3][1]-bas[top].a[3][3]-bas[top].a[3][4]-bas[top].a[3][5];
if(num>9||num<0)continue;bas[top].a[3][2]=num;
if(check(bas[top].a[3][1],bas[top].a[3][2],bas[top].a[3][3],bas[top].a[3][4],bas[top].a[3][5]))f6();
}
}
void f51(){
for(register int i=0;i<=9;i++){
bas[top].a[3][4]=i;
f5();
}
}
void f4(){
for(int i=0;i<=9;i++){
bas[top].a[1][5]=i;
int num=sum-bas[top].a[5][1]-bas[top].a[1][5]-bas[top].a[3][3]-bas[top].a[2][4];
if(num>9||num<0)continue ;bas[top].a[4][2]=num;
if(check(bas[top].a[5][1],num,bas[top].a[3][3],bas[top].a[2][4],bas[top].a[1][5]))f51();
}
}
void f3(){
for(register int i=0;i<=9;i++){
bas[top].a[2][5]=i;
int num=sum-bas[top].a[2][1]-bas[top].a[2][2]-bas[top].a[2][4]-bas[top].a[2][5];
if(num>9||num<0)continue ;bas[top].a[2][3]=num;
if(check(bas[top].a[2][1],bas[top].a[2][2],num,bas[top].a[2][4],bas[top].a[2][5]))f4();
}
}
void f31(){
for(int i=0;i<=9;i++){
bas[top].a[2][4]=i;
f3();
}
}
void f2(){
for(register int i=0;i<=9;i++){
bas[top].a[5][1]=i;
int num=sum-bas[top].a[1][1]-bas[top].a[3][1]-bas[top].a[4][1]-bas[top].a[5][1];
if(num>9||num<0)continue ;
bas[top].a[2][1]=num;
if(check(bas[top].a[1][1],num,bas[top].a[3][1],bas[top].a[4][1],bas[top].a[5][1]))f31();
}
}
void f22(){
for(int i=0;i<=9;i++){
bas[top].a[4][1]=i;
f2();
}
}
void f21(){
for(int i=0;i<=9;i++){
bas[top].a[3][1]=i;
f22();
}
}
void f1(){
for(register int i=0;i<=9;i++){
bas[top].a[5][5]=i;
int num=sum-bas[top].a[1][1]-bas[top].a[3][3]-bas[top].a[4][4]-bas[top].a[5][5];
if(num>9||num<0)continue ;
bas[top].a[2][2]=num;
if(check(bas[top].a[1][1],num,bas[top].a[3][3],bas[top].a[4][4],bas[top].a[5][5]))f21();
}
}
void f12(){
for(int i=0;i<=9;i++){
bas[top].a[4][4]=i;
f1();
}
}
void f11(){
for(int i=0;i<=9;i++){
bas[top].a[3][3]=i;
f12();
}
}
void does(){
bas[top].a[1][1]=s;
f11();
sort(bas,bas+top);
for(int i=0;i<top;i++){
for(int j=1;j<=5;j++){
for(int k=1;k<=5;k++){
cout<<bas[i].a[j][k];
}
cout<<endl;
}
cout<<endl;
}
}
int main(){
prim();
cin>>sum>>s;
does();
return 0;
}
