毒瘤题解

loj题目传送门

题目大意:有一个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;
}

这题我调了6个半小时,可能是我太弱了

转载于:https://www.cnblogs.com/ironwheel/p/9537811.html

【USACO 4.3.2】质数方阵相关推荐

  1. loj.ac:#10024. 「一本通 1.3 练习 3」质数方阵

    CSDN的博客 友键 题目描述 质数方阵是一个\(5×5\)的方阵,每行.每列.两条对角线上的数字可以看作是五位的素数.方格中的行按照从左到右的顺序组成一个素数,而列按照从上到下的顺序.两条对角线也是 ...

  2. 《信息学奥赛一本通》提高版题单

    第一部分 基础算法 第 1 章 贪心算法 #10000 「一本通 1.1 例 1」活动安排 #10001 「一本通 1.1 例 2」种树 #10002 「一本通 1.1 例 3」喷水装置 #10003 ...

  3. LOJ 一本通一句话题解系列:

    第一部分 基础算法 第 1 章 贪心算法 1):「一本通 1.1 例 1」活动安排:按照结束时间排序,然后扫一遍就可以了. 2):「一本通 1.1 例 2」种树:首先要尽量的往区间重叠的部分种树,先按 ...

  4. 一本通提高篇在线提交地址

    一本通提高篇 1 基础算法 1.1 贪心算法 1.1.1 P2018  [第一章例题1.1]活动安排正确: 9 提交: 17 比率: 52.94 % 1.1.2 P2021 [第一章例题1.2]种树正 ...

  5. USACO 1.5.3 SuperPrime Rib 特殊的质数肋骨

    题目描述: 农民约翰的母牛总是产生最好的肋骨. 你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们. 农民约翰确定他卖给买方的是真正的质数肋骨,是因为从右边开始切下肋骨,每次还剩下的肋骨上的数 ...

  6. 【USACO training】Chapter 1 入门

    整理的算法模板合集: ACM模板 目录 Section 1.1 介绍 Section 1.2 提交解决方案,任务类型,特殊问题 1.2.1 AcWing 1339. 你的旅途由此开始(字符串模拟) 1 ...

  7. 洛谷 P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib

    P1218 [USACO1.5]特殊的质数肋骨 Superprime Rib 题目描述 农民约翰的母牛总是产生最好的肋骨.你能通过农民约翰和美国农业部标记在每根肋骨上的数字认出它们.农民约翰确定他卖给 ...

  8. [USACO1.5]回文质数 Prime Palindromes

    题目描述 因为151既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151 是回文质数. 写一个程序来找出范围[a,b](5 <= a < b <= 100,000 ...

  9. 【codevs1246】丑数,STL与取模大质数的好处

    丑数 USACO 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 对于一给定的素数集合 S = {p1, p2, -, ...

  10. P1217 [USACO1.5]回文质数 Prime Palindromes——回文质数性质、打表

    [USACO1.5]回文质数 Prime Palindromes 题目描述 因为 151151151 既是一个质数又是一个回文数(从左到右和从右到左是看一样的),所以 151151151 是回文质数. ...

最新文章

  1. VMWare虚拟机与主机共享文件夹(如何安装VMWare tools)windows与windows共享
  2. HDU-4516 威威猫系列故事——因式分解 多项式分解
  3. 加载vue文件步骤_vue中.vue文件解析步骤详解
  4. 使用jquery进行多行表格数据验证
  5. 文献记录(part17)--VARCLUST: clustering variables using dimensionality reduction
  6. android 获取程序,Android获取桌面应用程序
  7. 网游服务器端设计思考:心跳设计
  8. 浅谈长连接的平滑重启
  9. 句句真研—每日长难句打卡Day18
  10. BLUES吉他学习笔记007 bluesrv[11]
  11. 那些一味顺从领导,不与领导顶嘴的人最后结局都怎么样了?
  12. 转座子可抑制mRNA翻译
  13. 【金猿技术展】视频矫正技术——基于参数估计的自由几何变换算法
  14. 【工具】PrimoCache和Qiling:快速缓存优化加速软件
  15. 理清web服务器跟应用服务器的基本概念(纯拷贝)
  16. 马云说:“未来是大数据的时代”
  17. webpack实现es6转换为es5
  18. RNA与DNA曾是一体?生命起源论或被颠覆
  19. Jfrog:烂泥蛙安装
  20. 数学思维在计算机学的应用,数学思维在生活中的应用

热门文章

  1. 上传2008文件服务器慢,为什么在Windows 2008 R2服务器上复制到本地UNC路径的速度如此慢?...
  2. go mysql stmt exec_Go语言操作MySQL
  3. anaconda打开python文本编辑器_【python】anaconda中打开IDLE(python 自带编辑器)
  4. Ubuntu 16.04 Apache https证书安装
  5. 第一次面试总结--中国电子科学研究院
  6. 基于SSM的猫头鹰轻博客系统
  7. 使用Jsoup完成网页爬虫
  8. java list map 效率_遍历Map和List的几种方法和性能比较
  9. 学计算机的银行从业人员,银行从业人员继续教育
  10. JavaScript 求和(字符串转换成数组、for循环求和)