主题:一个很难的问题
Lovely哆啦
[专家分:1360] 发布于 2007-04-05 17:30:00
方格取数
问题描述:
设有N*N的方格图(N<=8),我们将其中的某些方格中填入正整数,而其他的方格中则放
人数字0。如下图所示(见样例):
A
0 0 0 0 0 0 0 0
0 0 13 0 0 6 0 0
0 0 0 0 7 0 0 0
0 0 0 14 0 0 0 0
0 21 0 0 0 4 0 0
0 0 15 0 0 0 0 0
0 14 0 0 0 0 0 0
0 0 0 0 0 0 0 0
B
某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B
点。在走过的路上,他可以取走方格中的数(取走后的方格中将变为数字0)。
此人从A点到B点共走两次,试找出2条这样的路径,使得取得的数之和为最大。
输入:
输入的第一行为一个整数N(表示N*N的方格图),接下来的每行有三个整数,前两个
表示位置,第三个数为该位置上所放的数。一行单独的0表示输入结束。
输出:
只需输出一个整数,表示2条路径上取得的最大的和。
样例:
输入
8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
输出
67
回复列表 (共9个回复)
沙发
Lovely哆啦 [专家分:1360] 发布于 2007-07-30 08:47:00
为什么没人回帖呢??
板凳
wzc1996 [专家分:1680] 发布于 2007-07-30 11:34:00
没做出来
3 楼
天尝地酒 [专家分:870] 发布于 2007-08-08 09:07:00
我也是.
4 楼
snoopy7 [专家分:70] 发布于 2007-08-10 22:12:00
CLS
INPUT N
DIM B(N * 2 - 1), D(N * 2 - 1), C(N * 2 - 1)
INPUT Q, W, E
A(Q, W) = E
DO WHILE E <> 0
INPUT Q, W, E
A(Q, W) = E
LOOP
DO WHILE B(0) = 0
L = N * 2 - 2
DO WHILE B(L) = 1
B(L) = 0
L = L - 1
LOOP
B(L) = B(L) + 1
S = 0
FOR J = 1 TO L
S = S + B(J)
NEXT
IF S <> N - 1 THEN 10
Q = 1: W = 1
S = A(1, 1)
FOR I = 1 TO N * 2 - 2
IF B(I) = 0 THEN W = W + 1 ELSE Q = Q + 1
S = S + A(Q, W)
NEXT
IF S > O THEN O = S: FOR I = 1 TO N * 2 - 2: D(I) = B(I): NEXT
10 LOOP
Q = 1: W = 1
FOR I = 1 TO N * 2 - 2
IF D(I) = 0 THEN W = W + 1 ELSE Q = Q + 1
A(Q, W) = 0
NEXT
DO WHILE C(0) = 0
L = N * 2 - 2
DO WHILE C(L) = 1
C(L) = 0
L = L - 1
LOOP
C(L) = C(L) + 1
S = 0
FOR J = 1 TO L
S = S + C(J)
NEXT
IF S <> N - 1 THEN 10
Q = 1: W = 1
S = A(1, 1)
FOR I = 1 TO N * 2 - 2
IF C(I) = 0 THEN W = W + 1 ELSE Q = Q + 1
S = S + A(Q, W)
NEXT
IF S > R AND S <> O THEN R = S
20 LOOP
PRINT R + O
就是速度不行,11秒才出来
5 楼
moz [专家分:37620] 发布于 2007-08-11 10:56:00
这一题是需要保存路径的,跟上一题素数路径要求不同,
这就需要保存每个节点的位置信息,只需要找最大值即可
全部保存完后,根据大小选择,并显示方向位置信息即可.
如果只是需要最大的两个值,而不需要具体的路径
那连节点都不需要保存了,直接按上一题索数路径查找就好了.
6 楼
moz [专家分:37620] 发布于 2008-04-22 12:52:00
发件人: matodied <matodied@yeah.net>
发送时间: 2008年4月20日 18:58
收件人: moz@21cn.net <moz@21cn.net>
主题: 关于方格取数问题的另一种解法
方格取数问题,详见:
http://bbs.pfan.cn/post-224779.html
我最近做出来了这题,我的大致算法:
由于只许向下或向右走,因此不管怎么走,走的步数是一定的,为2N-2。可以定义一个数组c(n*2-2),存放每一步的信息。c(i)的取值只有两个:0表示第i步(即从走过的第i个方格到第i+1个方格)是向下走的,1表示第i步是向右走的。用回溯算法遍历c(从全0到全1),每得出一个走的方案,就调用过程st1,用来计算第一次走的过程中取到的数之和(注意:这个方案可能出现越界问题,即走到方格图外面,如果遇到这种情况,则此方案无效)。由于第一次走完后还要走第二次,则把所有可行的方案(第二次)全部遍历(从全0到全1),程序中用d数组保存第二次走的信息。在走第二次前,要把第一次已取到的所有数标成0。
程序(已标注释):以下代码隐藏:
[color=ffffff]DECLARE SUB st1 ()
DECLARE SUB st2 ()
OPTION BASE 1
CLS
DIM SHARED n, max, m
INPUT n
DIM SHARED a(n, n), b(n, n), c(n * 2 - 2), d(n * 2 - 2), kx(n * n), ky(n * n)
'a数组存放初始方格图,b数组存放每一次走后的方格图
'c数组存放第一次走的方案数据,d数组存放第二次走的方案数据
'kx数组存放方格图中所有非0数字的位置的x坐标,ky数组存放方格图中所有非0数字的位置的y坐标
j = 0 'j为方格图中非0数字个数
DO
INPUT x, y, z
IF x = 0 AND y = 0 AND z = 0 THEN EXIT DO
a(x, y) = z
j = j + 1
kx(j) = x
ky(j) = y '数字和位置存入数组
LOOP
max = 0
DO
FOR k = 1 TO j: b(kx(k), ky(k)) = a(kx(k), ky(k)): NEXT k '初始化b数组
FOR k = 1 TO n * 2 - 2: d(k) = 0: NEXT k 'd数组清零
m = a(1, 1): CALL st1 'm为目前取到的数字之和
'调用第一次行走过程
i = n * 2 - 2
DO '产生另外一套行走方案
c(i) = c(i) + 1
IF c(i) = 2 THEN
c(i) = 0: i = i - 1
IF i = 0 THEN PRINT max: END '方案已找完,输出最大和,结束
ELSE
EXIT DO
END IF
LOOP
LOOP
END
SUB st1 '第一次行走过程
xx = 1: yy = 1 'xx,yy为目前位置,初始为左上角
FOR k = 1 TO n * 2 - 2
IF c(k) = 0 THEN xx = xx + 1 ELSE yy = yy + 1
IF xx > n OR yy > n THEN EXIT SUB '如果越界,此方案无效,退出
m = m + a(xx, yy): b(xx, yy) = 0 '取数
NEXT k
mm = m '记下第一次取到的数之和
DO
m = mm: CALL st2 '调用第二次行走过程
IF m > max THEN max = m
i = n * 2 - 2
DO '产生另外一套第二次行走方案
d(i) = d(i) + 1
IF d(i) = 2 THEN
d(i) = 0: i = i - 1
IF i = 0 THEN EXIT SUB '第二次行走方案已找完,退出过程
ELSE
EXIT DO
END IF
LOOP
LOOP
END SUB
SUB st2 '第二次行走过程
xx = 1: yy = 1
FOR k = 1 TO n * 2 - 2
IF d(k) = 0 THEN xx = xx + 1 ELSE yy = yy + 1
IF xx > n OR yy > n THEN EXIT SUB
m = m + b(xx, yy)
NEXT k
END SUB[/color]
你的程序我没有具体验证过,大概思路我看了,这是比较直观的遍历方法.
也许,会有更优的择优录取办法的.......
7 楼
Mato完整版 [专家分:1270] 发布于 2008-04-22 13:23:00
moz,你????????
我发到你的邮箱里去就是不愿意让蜀山区的人看见,
你却……
8 楼
冷石_jasv [专家分:1570] 发布于 2008-05-10 16:45:00
[quote]moz,你????????
我发到你的邮箱里去就是不愿意让蜀山区的人看见,
你却……[/quote]
哈哈。。。
比赛?
要评分的?有奖品?
那把源程序发出来的人不是亏死了。。
9 楼
Mato完整版 [专家分:1270] 发布于 2008-05-11 17:05:00
其实我发了这个代码也没事,我还有更优的方法,你就算是把这代码背下来了,到复赛的时候照样吃亏。
因此我已经不怕发这个代码了。
我来回复