现代程序设计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高级程序设计
编写可维护性代码 可维护的代码遵循原则: 可理解性 (方便他人理解) 直观性 (一眼明了) 可适应性 (数据变化无需重写方法) 可扩展性 (应对未来需求扩展,要求较高) 可调试性 (错误处理方便定位) ...
随机推荐
- linux usermod修改用户所在组方法
usermod 用户名 -g 组名 -g<群组> 修改用户所属的群组. -G<群组> 修改用户所属的附加群组.
- eclipse安装Log4E插件以及简单使用
一. Log4E插件下载 下载地址:http://log4e.jayefem.de/content/view/3/2/ 二.安装Log4E插件 将下载下来的压缩包解压缩,如下图所示: 解压缩生成的[d ...
- 孟岩的c++ 的学习方法,这何尝有不是做人做事的方法呢?
“(孟岩)我主张,在具备基础之后,学习任何新东西,都要抓住主线,突出重点.对 于关键理论的学习,要集中精力,速战速决.而旁枝末节和非本质性的知识内容,完全可 以留给实践去零敲碎打. “原因是这样的,任 ...
- HeadFirst设计模式之策略模式
什么是策略模式:它定义了一系列算法,可以根据不同的实现调用不同的算法 大多数的设计模式都是为了解决系统中变化部分的问题 一.OO基础 抽象.封装.多态.继承 二.OO原则 1.封装变化,如把FlyBe ...
- BIG5编码表
Big5 (Traditional Chinese) character code table code +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F ...
- 安装win7 32位系统出现的问题解决办法
计算机意外地重新启动或遇到错误.Windows 安装无法继续.若要安装Windows,请单击“确定”重新启动计算机,然后重新启动安装”. http://www.baidusoso.net/ ...
- poj 1789 Truck History(最小生成树)
模板题 题目:http://poj.org/problem?id=1789 题意:有n个型号,每个型号有7个字母代表其型号,每个型号之间的差异是他们字符串中对应字母不同的个数d[ta,tb]代表a,b ...
- [原]Unity3D深入浅出 - 认识开发环境中的Component(组件)菜单
Component(组件)是用来添加到GameObject对象上的一组相关属性,本质上每个组件都是一个类的实例,比如在Cube上添加一个Mesh网格,即面向对象的思维方式可以理解成Cube对象里包含了 ...
- lnmp 安装环境之后discuz论坛排版乱的问题
服务器系统类型:centos 6.5 环境:使用lnmp官方安装shell安装 (http://lnmp.org/install.html) 在部署dz之后,访问页面 出现排版乱,资源不能加载的问题: ...
- iScroll-5拉动刷新功能实现与iScroll-4上拉刷新的一点改进
近来在学习移动设备的应用开发,接触了jQuery mobile,在网上查阅相关资料时发现一个叫”iScroll“的小插件.其实这个iScroll插件跟jQuery mobile没有多大关系,并不是基于 ...