1 / 18

The Primes 解题报告

The Primes 解题报告. 00108108 刘国栋 2003.7.6. 题目说明. 用数字填充 5×5 矩阵,使得: 每行 ( 左 -> 右 ) 、每列 ( 上 -> 下 ) 、两对角线 ( 左 -> 右 ) 的五个数字连成五位数的质数 每个质数的数字和为 sum 左上角数字为 digit 质数允许重复 质数不能以 0 开头. 题目说明 —— 例子. digit. sum=11 , digit=1 的一个解如右 左上角为 1 行、列、对角线均为质数 行、列、对角线数字和为 11 最左一列、最上一行不能有 0 质数允许重复: 13331.

Télécharger la présentation

The Primes 解题报告

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. The Primes解题报告 00108108 刘国栋 2003.7.6

  2. 题目说明 • 用数字填充5×5矩阵,使得: • 每行(左->右)、每列(上->下)、两对角线(左->右)的五个数字连成五位数的质数 • 每个质数的数字和为sum • 左上角数字为digit • 质数允许重复 • 质数不能以0开头

  3. 题目说明——例子 digit • sum=11,digit=1的一个解如右 • 左上角为1 • 行、列、对角线均为质数 • 行、列、对角线数字和为11 • 最左一列、最上一行不能有0 • 质数允许重复:13331

  4. 题目说明——输入输出 • 输入:两行 第一行数字和sum 第二行左上角数字digit • 输出: 输出所有可能的解,两个解用空行隔开

  5. 解法1:枚举法 • 24重循环,逐个确定矩阵中的每个元素 • 必须是五位数,最左一列、最上一行元素不为0 • 根据素数的限制,最右一列、最下一行不能是偶数(只能取 1 3 7 9,但是这样不太好实现) • 则每个位置的可能取值情况如图

  6. 枚举顺序 • 考虑到元素和为sum的限制,某些元素可以由已知元素直接确定 • 适当选择每个元素确定的顺序会减少需要枚举的元素数 • 顺序确定原则:尽可能多的由已知元素确定未知元素 • 右图是一种顺序:

  7. 枚举顺序 • 按照上面的顺序,复杂度: 96*108/29 • 右图是另一种顺序:枚举尽可能少的元素 • 按此顺序,复杂度: 96*107/29

  8. 素数判断 • 每确定好一个五位数后,都要进行素数判断,需要选择好的算法 • 用通用的素数判断法效率会很低 • 题目限定是五位数,sqrt(100000)=316,小于316的素数有65个,可以记录在数组中,每个素数判断最多需要65步 • 用优化的素数判断法:900MS

  9. 解法2:回溯法 • 枚举法是先填表格,在填表的过程中进行质数判断 • 考虑先进行质数判断,然后再填表 • 找到符合条件的五位数: 质数 数字和为sum • 用符合条件的五位数按照适当的顺序填充表格

  10. 质数计数 • Pi(n):小于等于n的质数的个数 • Pi(n) ~ n/ln(n) n pi(n) n/ln(n) 10 4 4.3 100 25 21.7 316 65 54.9 1,000 168 144.8 10,000 1229 1085.7 100,000 9592 8685.9 1,000,000 78498 72382.4

  11. 质数计数2 • 五位数的质数的个数是 N≈ pi(100,000)-pi(10,000) = 7600 • 实际的数目是8363:N=8363 • 符合数字和为sum的质数的个数: sum=23时最多,有757个

  12. 找五位数的算法:顺序扫描,找到的数是有序的找五位数的算法:顺序扫描,找到的数是有序的 • for(int i=10001;i<100000;i++) { if(数字和为sum) if(i为质数) { prime[num++]=i; head[i/10000]++; } } • head[i]记录i开头的数的个数 • 可以用head[i]建立搜索的索引

  13. 填充顺序的选择 • 填充第i行记做Hi,填充第j列记做Vj,填充对角线记做D1(左下->右上)D2(左上->右下) • 选择原则: • 尽可能多的前面的数字已经确定(已经排序,搜索快) • 每一步填充不要先确定后面的数字(判断冲突麻烦) • 则可以按照下面的顺序填充: • H1, V1, H2, V2, H3, V3, H4, V4, H5, V5,D1, D2

  14. 填充顺序

  15. 回溯法实现 • 每一步填充对应一个函数,编程实现非常麻烦 • 填充时不能和已经填上的数字矛盾 • 可以利用已经填好的数字进行剪枝、优化,否则时间开销太大 • 比如当某一行(列)中已经确定了三个元素时,可以先检查其元素和是不是超过sum • 需要判断素数时,可以用后面的优化 • 效果: 530MS

  16. 枚举法中素数判断的优化 • 从回溯法得到启发: • 可以预先扫描所有五位数,记录数字和为sum且是素数的所有五位数 • 数组中记录的素数是有序的,素数判断时可以用二分法检索:log2757≈10 • 更进一步:记录符合条件的素数的同时记录第一个数字是i的素数的个数,建立索引,减小搜索范围 • 效果: 370MS

  17. 结论 • 一定范围内的数的素数判断,可以用查找代替,以提高效率: • 遍历范围内的数,记录素数, • 记录是有序的,二分法查找 • 填充时选择好的填充顺序非常重要 • 两种方法选择不同的填充方式 • 好的剪枝可以提高效率

  18. Thank You !

More Related