现代程序设计homework-02
总体思路
(1)单维数组
单维数组的思路的构建在第一次作业已经完成了,简单来说就是根据贪心策略从头到尾累加,一旦遇到当前累加和变为负数,就将累加和清零,继续遍历数组中的元素,算法的时间复杂度是O(n)的。这次作业又加了一个条件,就是存在结果溢出的情况。由于笔者不知道结果到底会有多大,所以没敢开个64位整型敷衍了事,就写了高精度处理数据溢出的情况,也就是把每个数都用一个数组表示,数组中每一位代表数字的每一位,运算根据加减法的原理进行数组操作。
测试样例:结果:
代码:
void solve1()
{
int i,j,s[],a[],ans[];
memset(s,,sizeof(s));
memset(ans,,sizeof(ans));
ans[]=;
s[]=;
int flag;
for (i=;i<=m;i++)
{
if (s[s[]]<)
{
memset(s,,sizeof(s));
s[]=;
}
flag=;
memset(a,,sizeof(a));
a[]=;a[]=data[][i];
if (a[]<)
{
a[]=-a[];
flag=;
}
while (a[a[]]>)
{
a[a[]+]=a[a[]]/;
a[a[]]=a[a[]]%;
a[]++;
}
int l=s[];
if (a[]>l) l=a[];
if (flag) {
for (j=;j<=l;j++)
{
s[j]-=a[j];
if (s[j]< && j<l){
s[j]+=;
s[j+]-=;
}
}
while (s[l]== && l>)
l--;
s[]=l;
}else {
for (j=;j<=l;j++)
{
s[j]+=a[j];
if (s[j]>)
{
s[j+]+=s[j]/;
s[j]=s[j]%;
}
}
if (s[l+]>)
l++;
s[]=l;
}
int max=;
if (s[s[]]>){
if (s[]>ans[]){
max=;
}else if (s[]<ans[]) {
max=;
}else {
for (j=s[];j>;j--)
if (s[j]>ans[j])
{
max=;
break;
}
else if (s[j]<ans[j])
{
max=;
break;
}
}
}
if (max==){
for (j=;j<=s[];j++)
ans[j]=s[j];
}
}
for (i=ans[];i>;i--)
cout<<ans[i];
cout<<endl;
}
solve1
(2)二维数组和最大子矩形
思路其实是单维思路的扩展,由于矩形的各列它们的行数是相等的,我们可以在预处理的时候将每一列的所有前i行的和计算出来(i<n),这样我们就可以在枚举矩形下边的时候在枚举行数,将这么多行的和当作是一维数组的各个元素,在通过一维的算法求和取最大就可以了。
测试样例:结果:
代码:
void solve2()
{
int i,j,k;
int ans=;
memset(sum,,sizeof(sum));
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
sum[j][i]=sum[j][i-]+data[i][j];
}
for (i=;i<=n;i++)
for (k=;k<=i;k++)
{
int temps=;
for (j=;j<=m;j++)
{
int a=sum[j][i]-sum[j][k-];
if (temps<) temps=;
temps+=a;
if (temps>ans)
ans=temps;
}
}
cout<<ans<<endl;
}
solve2
(3)二维数组最大和联通块
这题不评价,太难了,当初有想过联通性状态压缩的动态规划,不过由于笔者能力有限,实现起来难度巨大,于是放弃,不过即使这么做,也不能在理想的时间内解决题目限定规模的问题。于是,既然怎么做都会运行很久,那笔者就干脆来了个破罐子破摔,写了个暴力枚举(至少能输出正确结果。。。)。主要的思路就是对于n*m矩阵中每个元素枚举它们的选取状态,然后判断这种取法是否联通。一开始枚举状态笔者采用的深度优先搜索,从第一行第一个元素开始枚举其状态,接着递归一个一个的枚举,直到枚举完这n*m个元素的状态,然后再判断是否联通。机智的读者可能发现,这里是可以剪枝优化的,就是某种状态是否联通,我们并不一定要在最后一个元素枚举完后才能判断出来,其实在每一个枚举完后我们就能判断当前的状态是否有可能最终联通,判定的条件就通过遍历之前的矩阵来判断是否有选取的元素无法到达当前枚举元素所在的行。这样做可以剪掉很多不必要的枚举。而枚举完所有元素状态的判断是否连通的方法是用染色,随便从当前状态中选取一个选中的初始状态,然后进行搜索遍历,由于笔者之前枚举是用深度优先搜索,这里觉得递归里面再套个递归不太好,于是染色的步骤就通过广度优先搜索来实现。当染完色后,检查每个元素,如果存在选中的元素未被染色那么这个结果就是不联通的,反之即是联通,就可以算出和然后更新当前答案。这题单独说点感想吧:题目太恶心了,都有退课的冲动了。
测试数据:结果:
代码:
void dfs(int x,int y)
{
if (x>n)
{
if (mode==)
solve3();
else
solve7();
return;
}
int xx=x,yy=y+;
if (yy>m)
{
yy=;
xx++;
}
pass[x][y]=;
dfs(xx,yy);
pass[x][y]=;
dfs(xx,yy);
}
dfs
void solve3()
{
memset(qq,,sizeof(qq));
memset(pb,,sizeof(pb));
int h=,t=;
int i,j,k;
for (i=;i<=n;i++)
{
for (j=;j<=m;j++)
if (pass[i][j]==)
break;
if (j<=m)
break;
}
pb[i][j]=;
qq[]=(i-)*m+j;
while (h<=t)
{
int x,y;
x=(qq[h]-)/m+;
y=qq[h]%m;
if (y==) y=m;
for (k=;k<;k++)
{
int xx=x+change[k][],yy=y+change[k][];
int temp;
if (xx< || xx>n || yy< || yy>m)
continue;
temp=(xx-)*m+yy;
if (pass[xx][yy]== && pb[xx][yy]==)
{
qq[++t]=temp;
pb[xx][yy]=;
}
}
h++;
}
int flag=,temps=;
for (i=;i<=n;i++)
for (j=;j<=m;j++)
if (pass[i][j]==)
{
temps+=data[i][j];
if (pb[i][j]==)
flag=;
}
temps=temps;
if (flag== && temps>aans)
aans=temps;
}
solve3
(4)水平相连
虽说题目描写说是在(3)的基础上,但考虑到后面有个/v /h /a 这种东西的存在,我就姑且认为这个/h模式选取的是矩阵吧。其实水平相连的话和原始的并没有什么区别,我代码里写的思路是按照(2)的顺序来求最大值的同时,通过类似的方法求出最小值(遍历顺序一样不过和大于零就清零,取最小),然后用整行的和减掉这个最小值,和求出的最大值进行比较。这么做的原理其实就是考虑到横跨的情况其实就是一行中头取一段,尾取一段,又由于一行的和是固定的,这样我们用一行的和减去求出的最小连续块的和就能得到横跨的选取的最大值。在实现了这个算法后,笔者又想到了一种方法,其实就是把列压缩改成行压缩的形式,然后将数组的列数扩大一倍(后半段与前半段相等),然后按照(2)的方法(这里一开始枚举列),只要在枚举的时候限定下长度不大于m,也能得出答案,这样做代码量少了,但空间复杂度大了。
测试数据:结果:
代码:
void solve4()
{
int i,j,k;
int ans=;
memset(sum,,sizeof(sum));
for (i=;i<=n;i++)
{
for (j=;j<=m;j++){
sum[j][i]=sum[j][i-]+data[i][j];
sum[j+m][i]=sum[j][i];
}
}
for (i=;i<=n;i++)
for (k=;k<=i;k++)
{
int temps=,templ=,asum=,min=;
for (j=;j<=m;j++)
{
int a=sum[j][i]-sum[j][k-];
if (temps<) temps=;
temps+=a;
if (temps>ans)
ans=temps;
if (templ>) templ=;
templ+=a;
if (templ<min)
min=templ;
asum+=a;
}
if (asum-min>ans)
ans=asum-min;
}
cout<<ans<<endl;
}
solve4
垂直相连也是一样的(我会说之间将行列对换就能解决吗?)
(5)水平垂直相连
思路就是上面我的两种解法的结合,首先将行数扩大一倍,然后用(4)的方法对于水平方向进行处理,当前枚举矩形的行数保证<=n。
测试数据:结果:
代码:
void solve6()
{
int i,j,k;
int ans=;
memset(sum,,sizeof(sum));
for (i=;i<=*n;i++)
{
int ii=i;
if (ii>n)
ii-=n;
for (j=;j<=m;j++)
sum[j][i]=sum[j][i-]+data[ii][j];
}
for (i=;i<=*n;i++)
for (k=;k<=i;k++)
{
if (i-k>=n)
continue;
int temps=,templ=,asum=,min=;
for (j=;j<=m;j++)
{
int a=sum[j][i]-sum[j][k-];
if (temps<) temps=;
temps+=a;
if (temps>ans)
ans=temps;
if (templ>) templ=;
templ+=a;
if (templ<min)
min=templ;
asum+=a;
}
if (asum-min>ans)
ans=asum-min;
}
cout<<ans<<endl;
}
solve6
(7)/v /h /a
思路和(3)类似,不同之处只是在判断是否连通时染色的规则稍加改变。之前染色是的规则是如果相邻元素在矩阵之外就跳过,现在由于水平垂直都相连了,于是我们就矩阵之外的元素变为对应矩阵内的元素。
测试数据:结果:
代码:与(3)类似。
设计过程
设计还是采用面向过程的方法(我知道很挫)。首先开个公共变量mode,根据命令行参数改变mode值来选取模式。各种模式对应一个void函数,solve1(), solve2()...。这样做的好处就是代码比较好组织,思路体现得比较直观,缺点就是代码重复度比较大,过于冗长。这两天试着用面向对象的方法来写,但由于之前没有这方面的经验,又临近截至日期了,所以没有完成。
单元测试
可能是用面向过程的方法设计,单元测试一直失败,没能完成这项的测试。
开发评估
Personal Software Process Stages |
时间百分比(%) |
实际花费的时间 (分钟) |
原来估计的时间 (分钟) |
|
Planning |
计划 |
|||
· Estimate |
· 估计这个任务需要多少时间,把工作细化并大致排序 |
4.7 | 30 | 30 |
Development |
开发 |
|||
· Analysis |
· 需求分析 (包括学习新技术) |
23.8 | 150 | 30 |
· Design Spec |
· 生成设计文档 |
4.7 | 30 | 30 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
4.7 | 30 | 30 |
· Coding Standard |
· 代码规范 (制定合适的规范) |
4.7 | 30 | 30 |
· Design |
· 具体设计 |
9.5 | 60 | 60 |
· Coding |
· 具体编码 |
19 | 120 | 120 |
· Code Review |
· 代码复审 |
4.7 | 30 | 30 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
4.7 | 30 | 30 |
Reporting |
总结报告 |
|||
|
4.7 |
30 |
30 | |
|
9.5 | 60 | 60 | |
Total | 总计 | 100% |
总用时 630 |
总估计的用时 510 |
感想
其实总体来说这次作业还是不难的,不过有bug般的/a 模式的存在着就让学习时间增加了非常多。很遗憾单元测试没有做出来,早知道一开始把研究/a 情况的时间去学习C#面向对象编程方面的东西了。下次一定这样做,努力做出老师的所有要求来。
现代程序设计homework-02的更多相关文章
- 标准C程序设计七---02
Linux应用 编程深入 语言编程 标准C程序设计七---经典C11程序设计 以下内容为阅读: <标准C程序设计>(第7版) 作者 ...
- 现代程序设计homework——04
题目: 详见:http://www.cnblogs.com/xinz/p/3341551.html 题目本身确实很难,“很难想到一个比较优雅的算法”,这是一个老师请来专门讲解这道题的大牛的原话.确实, ...
- vs2015c++/MFC入门知识全集/实例规范书籍视频下载孙鑫c++对话框计算器基础控件使用教程系列
VIP教程可免费看.可免费下载前部分试看教程地址:http://dwz.cn/4PcfPk免费下载地址:http://dwz.cn/mfc888 本课程目录 67章 [MFC项目开发第01天]Wind ...
- 软工+C(9): 助教指南,持续更新...
上一篇:提问与回复 下一篇:从命令行开始逐步培养编程能力(Java) 目录: ** 0x00 Handshake ** 0x01 点评 ** 0x02 评分 ** 0x03 知识储备 ** 0x04 ...
- python奇闻杂技
第一天 01 从计算机到程序设计语言 02 python环境配置 03 实例一:温度转换 04 python语法分析 第二天 01 深入理解python语言 02 实例二,python蟒蛇配置 03 ...
- 2012年游戏软件开发独立本科段01B0815自考科目
01B0815自考科目 课程代码[学分] 课程名称 03708[02] 中国近现代史纲要 03709[04] 马克主义基本原理概论 03684[10] 综合英语(四) 01042[05] 应用数学 0 ...
- 20145219 《Java程序设计》第02周学习总结
20145219 <Java程序设计>第02周学习总结 教材学习内容总结 类型:基本类型.类类型(参考类型) 基本类型: 整数:short占2字节,int占4字节,long占8字节 字节: ...
- js程序设计02——变量、作用域问题
首先,ECMAScript中的数据类型分为基本类型.引用类型,基本类型的访问操作是按值的.引用类型的值是保存在内存中的对象,操作对象时,实际上操作的是对象的引用,而非对象自身.“javascript高 ...
- 20145218 《Java程序设计》第02次实验报告
北京电子科技学院(BESTI)实验报告 课程:Java程序设计 班级:1452 指导教师:娄嘉鹏 实验日期:2016.04.12 实验名称:Java面向对象程序设计 一.实验内容 初步掌握单元测试和T ...
- 读书笔记(02) - 可维护性 - JavaScript高级程序设计
编写可维护性代码 可维护的代码遵循原则: 可理解性 (方便他人理解) 直观性 (一眼明了) 可适应性 (数据变化无需重写方法) 可扩展性 (应对未来需求扩展,要求较高) 可调试性 (错误处理方便定位) ...
随机推荐
- 如何在DJANGO里获取?带数据的东东,基于CBV
用DEF的,有现成的,而用CLASS的,就要作一下变通. 如下: if self.request.GET: if self.request.GET.get('search_pk'): search_p ...
- Linux中的栈:用户态栈/内核栈/中断栈
http://blog.chinaunix.net/uid-14528823-id-4136760.html Linux中有多种栈,很容易弄晕,简单说明一下: 1.用户态栈:在进程用户态地址空间底部, ...
- jquery.dataTables插件使用例子详解
DataTables是一个jQuery的表格插件.这是一个高度灵活的工具,依据的基础逐步增强,这将增加先进的互动控制,支持任何HTML表格 效果图 代码 <!doctype html> & ...
- 常用的富文本框插件FreeTextBox、CuteEditor、CKEditor、FCKEditor、TinyMCE、KindEditor ;和CKEditor实例
http://www.cnblogs.com/cxd4321/archive/2013/01/30/2883078.html 目前市面上用的比较多的富文本编辑器有: FreeTextBox 一个有很多 ...
- ENVI Services Engine5.1 应用开发入门教程
原文地址: ENVI Services Engine5.1 应用开发入门教程_ENVI-IDL中国_新浪博客 http://blog.sina.com.cn/s/blog_764b1e9d0102uy ...
- Android数据存储(三)——SQLite
如果需要一个更加健壮的数据存储机制,则需要使用一个关系型数据库,在Android上,则为SQLlite. SQLite的特点:轻量级.嵌入式的.关系型数据库.可移植性好,易使用,小,高效且可靠,与使用 ...
- IE9 表格错位bug
最近做项目的时候,出现一个只在原生IE9(非模拟)下的bug. bug图片如下: 以上两个模块的html代码和样式都是一样的,然而下面的显示却出现了各种对齐的bug. 用IE9的调试器查看,代码完全一 ...
- Ubuntu 12.04下搭建Qt开发环境
http://download.qt.io/official_releases/qt/ Ubuntu 环境下Gtk与Qt编译环境安装与配置(系统环境是Ubuntu 12.04) 1.配置基础开发环境G ...
- Innodb 锁系列1 同步机制
同步机制 Innodb实现了不依赖于平台的mutex,rwlock. 1. 全局变量 对于mutex, rwlock,都有一个全局链表. 1. mutex全局链表:mutex_list 2. rwlo ...
- BZOJ_3172_[TJOI2013]_单词_(AC自动机)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=3172 \(n\)个单词组成一篇文章,求每个单词在文章中出现的次数. 分析 这道题很像BZOJ_ ...