1735 字数统计 (HDU)

16 篇文章 0 订阅

题意理解 

给出一段N*L的01矩阵,矩阵的一个值代表一个文章的一个字,整个矩阵就是一段文字,0表示模糊(可能有值,也可能无),1表示有字。已知开头两个00是段落的标记,若文章原段落数是M,求0表示的模糊字最少多少?

问题分析

用贪心算法

过程分两步:第一步提取文章最多段落信息(开头是两个或两个以上0的情况),信息包括段落数countM,段落内0个数,段落尾0个数。第二步正式用贪心,要求最终在M个段落下0包含字最少,那就要求合并countM个段落数为M个段落,段落内的0肯定是包含字的,必须算在内,段落尾的0包不包含看该段落有没有被合并,合并了就是包含字的,没合并就不包含字。还有一部分0是段落开头,如果段落没被合并就不包含字,如果段落合并就包含字,长度固定为2。以上三种情况综合起来,合不合并一段关键看段落尾空白多少,要保证最终包含字的0最少,那么合并的段落尾空白越短越好,可以对段落尾0数从小到大排序,需要合并几段就从小到大取几个,再加上段落开头固定的2。

此外,题意隐含一个信息,文章默认有一个段落,最后一段必须独立,不管段落尾空白数量,因为合并不了。与上面的分析结合起来,就是排序尾0数时,不考虑最后一段!

其他

用时耗费点

刷题判断逻辑:系统要求循环输入-输出过程来判断;系统支持的循环过程必须是活循环(可断),死循环报超时!

while(1)

{cin>> N...}

以上方式必超时。

while(cin>>N...)

{}

以上方式可行。

效率分析:我的算法时间是1185ms,参考代码时间是296ms!这就是差距。思路上差异如下

没想到的

没想到最后一段尾0必须保留,

对段落信息数据结构的考虑,想的是段内0,段尾0,段头默认2,从后面用的情况来看,只用段内0,段尾0+端头2合二为一。思路里段落序号,段内0,段落尾0三者必须一致,不可单独排序,实际上根据要求,完全可以先累计段内0,排序段落尾0+端头2,取其前几个相加即可。

想的不好的

抽取段落信息,我的思路是

循环读取每一行:

判断开头是不是两个0,如果是,

       判断上一行尾是不是0;如果是

              判断行号是不是大于0,如果是

                    数上一行尾0数,保存

              否

                     不做操作

       否

             数当前行0数(包含头两位0),保存

       数当前行0数(包含全部0),保存

问题是尾0数了两遍,重复。参考代码思路是判断下一行是否是双0,如果是,当前段落计算尾0,计算当前行0计入当前段落;...这样就不用重复统计。

贪心算法实现,我的思路是

从尾0列表中(除去最后一个),每次选一个最大的尾0纪录作为保留段落,然后置为-1,直到选出M个段落。

参考代码思路,直接对尾0列表排序,对所有段内0累计,加上尾0排序后的从小到大的前countM-M个数即可。

 

总结就是,自己的思路停留在贪心的方法上,缺少将贪心集合到题目上的运用能力。删改增可以在灵活一点。下一步眼界看到题目本身的特点,而不是局限方法上。方向上,不再将数量作为最重要的方面,而是一题一题刷透,学到知识,拔掉思维里僵化的刺,脑子能学的活一点再活一点,一点一点流动起来。

代码链接:

自己代码:https://github.com/xierensong/learngit/blob/master/hdu/h1735.cpp

参考代码:https://blog.csdn.net/u013615904/article/details/77620103

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值