CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
可用分押宝游戏火热进行中... 专题改版:Java Web 专题
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  专题开发/技术/项目 >  数据结构与算法

求一个算法,是对数组进行操作的。

楼主efei(爱琴海)2003-12-04 11:52:22 在 专题开发/技术/项目 / 数据结构与算法 提问

一个二维数组(假设下标从1开始),每个元素的值非0即1。  
  现要从那些值是1的元素中找出n个元素,使得n个元素的列值之和为S。同时,这n个元素的行值不能重复,也就是说,一行最多只能选一个。  
  比如:  
  1   0   0   1  
  0   1   1   0  
  1   0   0   1  
  n=2,S=5  
  这里面有两组解:a[1][1]、a[3][4]和a[1][4]、a[3][1]  
  我只要一组就够了,不需要全部的解。但是要能判断出有无解  
  最后返回的结果只要知道列值,也就是1和4  
  请高手给个算法,分数嘛不是问题,给多少都没有问题。  
  问题点数:100、回复次数:6Top

1 楼ywqzxj(午青)回复于 2003-12-04 13:10:15 得分 10

简单搜索加一些剪枝判断就可以了,问一下数组的维数有没有大致范围?Top

2 楼huhuhu5()回复于 2003-12-04 13:27:30 得分 10

用回溯把1  
  参考下     八皇后问题  
  具体的     不用说了吧!Top

3 楼efei(爱琴海)回复于 2003-12-04 13:28:24 得分 0

就是二维的。Top

4 楼ZhangYv(迎着朝阳,走向地狱)回复于 2003-12-04 13:40:44 得分 80

不用那么麻烦。找出矩阵中所有为1的元素,标为二元组<i,j>   =   1  
  如果有K个这样的二元组存在,要求找出其和为S的集合,就是取一个组合数:  
  C(K,S)   如果K   >=   S则有解Top

5 楼ZhangYv(迎着朝阳,走向地狱)回复于 2003-12-04 13:43:18 得分 0

列值之和为S。同时,这n个元素的行值不能重复...就是生成时候再加以判断是否满足这个约束Top

6 楼efei(爱琴海)回复于 2003-12-04 20:08:45 得分 0

没有人回答我,我自己凑啊凑啊,嘿嘿,凑出来了  
   
  Sub   Assign(ByVal   s   As   Integer,   ByVal   n   As   Integer,   a()   As   Integer)  
  Dim   i   As   Integer                                 '用来记录intArr()的当前元素  
  Dim   j   As   Integer                                 '用来记录二维数组当前的行数  
  Dim   k   As   Integer                                 '在一行内搜索时用来记录列值  
  Dim   intArr()   As   Integer                   '存放分配好的分数的数组,二维的  
  Dim   blnIsDown   As   Boolean                 '是否在往下搜索  
  Dim   intTopRow   As   Integer  
  '初识化变量  
  blnIsDown   =   True                                 '一开始是往下搜索的  
  intTopRow   =   0  
  ReDim   intArr(n   -   1,   1)   As   Integer  
  i   =   0:   j   =   0  
  '开始探索  
  Do   Until   i   =   n  
          k   =   0  
          Do   Until   a(j,   k)   =   1   And   k   +   1   <=   s                   '循环找到本行第一个能取的元素  
                  k   =   k   +   1  
                  If   k   >   UBound(a,   2)   Then  
                          Exit   Do  
                  End   If  
          Loop  
          If   k   <=   UBound(a,   2)   Then                                       '判断是否找到  
                  '找到  
                  blnIsDown   =   True  
                  intArr(i,   0)   =   k   +   1                                         '记录列值(分数)  
                  intArr(i,   1)   =   j                                                 '记录行值,为后面的回溯做准备  
                  a(j,   k)   =   -1                                                         '置成-1,表示这个元素已经遍历过了。同时不把它置0是因为回溯时要恢复  
                  s   =   s   -   k   -   1                                                       '剩下的总分相应地减少  
                  i   =   i   +   1                                                               '指向下一个元素  
                  If   s   =   0   And   i   <>   n   Then  
                          '用的过多,再在本行之内搜索  
                          i   =   i   -   1  
                          intArr(i,   0)   =   0  
                          s   =   s   +   k   +   1  
                  ElseIf   i   =   n   And   s   <>   0   Then  
                          '分用少了,剩下好多  
                          i   =   i   -   1  
                          intArr(i,   0)   =   0  
                          s   =   s   +   k   +   1  
                  Else  
                          j   =   j   +   1  
                  End   If  
          Else  
                  '本行已经空了,要往回回溯  
                  If   blnIsDown   =   False   Or   j   =   UBound(a)   Then  
                          If   j   =   intTopRow   Then  
                                  '说明已经回溯到头了,这个时候要下到第二行  
                                  j   =   j   +   1  
                                  intTopRow   =   intTopRow   +   1  
                          Else  
                                  For   k   =   0   To   UBound(a,   2)  
                                          a(j,   k)   =   Abs(a(j,   k))  
                                  Next  
                                  If   intArr(i   -   1,   1)   =   j   -   1   Then  
                                          i   =   i   -   1               '退到上一个  
                                          s   =   s   +   intArr(i,   0)               '这个如果是在上一行吃的,则要退回,否则不退  
                                          intArr(i,   0)   =   0         '把上一个的清空  
                                  End   If  
                                  If   j   =   UBound(a)   Then  
                                          blnIsDown   =   False  
                                  End   If  
                                  j   =   j   -   1  
                          End   If  
                  Else  
                          j   =   j   +   1  
                  End   If  
          End   If  
  Loop  
  End   SubTop

相关问题

  • 数组算法??
  • 数组操作
  • 数组操作
  • 数组对掉,请看看,一个简单算法
  • 对 checkbox 控件数组的操作,这么操作不对吗?
  • 对于一个离散数组,用什么算法实现以下……
  • 数组正规化算法 求教
  • 数组拆分的算法问题
  • 求数组移位的算法
  • ◆挑战cookies字典数组算法

关键词

  • 数组
  • intarr
  • inttoprow
  • blnisdown
  • 元素
  • 搜索
  • 二维
  • ubound
  • 列值
  • 一行

得分解答快速导航

  • 帖主:efei
  • ywqzxj
  • huhuhu5
  • ZhangYv

相关链接

  • CSDN Blog
  • 技术文档
  • 代码下载
  • 第二书店
  • 读书频道

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo