|---|---|---|---|---|
| 1 | 1 | 3 | 5 | 1 |
|---|---|---|---|---|
| 3 | 3 | 2 | 0 | 3 |
|---|---|---|---|---|
| 3 | 0 | 3 | 2 | 3 |
|---|---|---|---|---|
| 1 | 4 | 0 | 3 | 3 |
|---|---|---|---|---|
| 3 | 3 | 3 | 1 | 1 |
|---|---|---|---|---|
(图1)
图1显示了一个正方形。每行,每列和两个对角线可以读作五位素数。从左到右读取行。列从上到下读取。两个对角线都是从左到右读取的。使用INPUT.TXT文件中的数据,编写一个构造这样的正方形的程序。
素数必须具有相同的数字总和(示例中为11)。 正方形左上角的数字是预先确定的(示例中为1)。
素数可以在同一个方格中多次使用。
如果有多种解决方案,则必须提供所有解决方案。 五位素数不能以零开头,即00003不是五位素数。
输入数据
11 1
我试图在IOI'94竞赛中提出一个问题 - 问题3 - The Primes。
我已经构建了大部分辅助函数......
问题:问题是我不知道如何填充数组或使用回溯功能来继续检查:(。任何人都可以帮我吗?如何填写2D数组以便它包含素数表中的值,并且总和在所有角度都是正确的?
* NB:生成5位数素数的Eratosthenes筛选方法,也可以过滤以X开头且值总和为M *
的值的能力完整问题:http://olympiads.win.tue.nl/ioi/ioi94/contest/day1prb3/problem.html
添加值的预期顺序,只是不知道该怎么做:(。
1 2 3 4 5
6 13 14 12 15
7 16 11 18 19
8 10 20 22 23
9 17 21 24 25
答案 0 :(得分:4)
根据你所写的内容,我假设你已经有了一个包含5位数素数的列表。 过滤列表,使其仅包含具有正确数字总和的素数。
您需要一个有效的函数来检查有效的正方形,给定列中的1到5个数字。 (很明显,列数确定了其他行和对角线。因此,如果第1列的第3位是7,但没有以7开头的素数,我们知道我们不能使用此素数第一列。如果不查看所有其他数字,这将提前修剪您的搜索树。)
您需要另一个函数来获取在位置n(1..5)处具有特定数字的所有有效素数的集合。也许您想要预先计算并将其存储在某个树或数组中。
主要工作是在有效的情况下完成的,必须检查行和对角线是否存在素数,其中的数字位于到目前为止由列中的素数确定的位置。
然后解决方案列表是:
[ (c1, c2, c3, c4, c5) | c1 <- primes, valid [c1],
c2 <- primes, valid [c1,c2],
c3 <- primes, valid [c1,c2,c3],
c4 <- primes, valid [c1,c2,c3,c4],
c5 <- primes, valid [c1,c2,c3,c4,c5] ]
或者,强制要求:
for each c1 in primes
if valid(c1) then foreach c2 in primes
if valid(c1,c2) then foreach c3 in primes
if valid(c1,c2,c3) then foreach c4 in primes
if valid(c1,c2,c3,c4) then foreach c5 in primes
if valid(c1,c2,c3,c4,c5) then print solution
附录:由于我们只需要查找以某些数字的序列开头的数字,因此可以提高解决方案的效率。 考虑给出c1,c2和c3以及有效()即将检查第3行的情况。它取c1,c2和c3的第3位数字,我们可以将它们解释为必须出现的数字的前3位数字在第3行中。我们只需要用零填充它,然后可以检查我们是否知道大于这个数的素数,但差值必须小于100(这样才能保留前导数字)。但是如果我们有一个被排序的素数数组,那么这个数组只需要一个二进制搜索。