work2
回答问题:
描述在这么多相似的需求面前, 你怎么维护你的设计 (父类/子类/基类, UML, 设计模式, 或者其它方法) 让整个程序的架构不至于崩溃的?
答:诚然,问题给出了很多选项如-a,-v,-h。但我觉得其架构并不复杂,-v,-h以及它们的组合其实是基于普通的最大权矩阵问题的,因而我认为这三类可分在一起作为一个original.h文件,然后带有-a的单独分类。
给出你做单元测试/代码覆盖率的最终覆盖率的报告, 用截屏显示你的代码覆盖率
答:见GITHUB附件。
你在这个作业中学到了什么? 有什么好的设计值得分享? 感想如何 (太容易 / 太难 / 太无趣)?
答:学到了如何合理架构带有命令行参数的C程序,如何计算覆盖率。
问题分析
在一维情况下我们已经分析得到了基于长度n的O(n)时间复杂度的算法。那么我们可以先考虑在二维情况下是否可以得到基于长度n宽度m的O(m)时间复杂度的算法。如我在作业1里分析。设s[x][y]为以坐标(0,0)为左上角,(x,y)为右下角的点所形成的的矩形的加和。以(a,b)(x,y)构成的矩形的值为,(s[x][y] - s[a-1][y])-(s[x][b-1] - s[a-1][b-1]),不具备一维时的单调性,只能通过在此枚举一行。时间复杂度为O(m*n*n),无法达到最好的O(m*n)。
也就是说对于普通的问题,我们只需要枚举2行的组合即先枚举i再枚举小于等于i的j,加和j-i的区间,1维处理就可以了。
而对于-v的垂直相连参数,是很容易转化为普通问题的,普通问题中只考虑j-i的区间,而这里再考虑下i-n与0-j的区间就可以了,时间复杂度也为O(m*n*n)。
而对于-h的水平相连参数,我们可以从转化出的一维问题中考虑。对于1维情况下如果收尾相连应该如何处理。一开始我考虑的是复制一遍贴在右边,但其实实现起来限制过于复杂。如果选择了超越经线0的矩形其实就是踢掉了中间的一块矩形,于是只需要找到最小的矩形,然后用正行的权减去它,与普通解想比较即可。
而对于-a参数,一开始由于我自己给它定义了宽度不超过16,我寻思可以用连通性状态压缩动态规划做,但由于之后改成了32,只能使用搜索加剪枝。经过并查集缩点之后(将正权点加合在一起作为一个点,并认为它的负权为0),其实相当于是求一个图的最大权联通子图。由于时间不够,-a参数的1我还没有完成,我的思路是这样的,先算出每个点两两之间距离,对于每个正点维护一棵以负权点到该正节点距离为重量以节点编号为编号的treap,在深度优先搜素的状态空间中,当前状态已经选好的点在每颗treap中,然后对于接下来考虑的点,先比较是否能刷新其中的任意一个treap,如果不能刷新代表本质上无法得到更优解,否则入堆,计算此时加上最小距离点之外所有权值和是否能达到已经算出的较优不行则剪枝。
original.h
#ifndef ORIGINAL_H_INCLUDED
#define ORIGINAL_H_INCLUDED
int maxsumline(int *p,int size)
{
int i;
int sum,ans;
sum=0;
ans=-1000000;
for(i=0;i<size;i++)
{
if(sum<0)
sum=0;
sum+=p[i];
if(ans<sum)
ans=sum;
}
return ans;
}
int maxsumcycle(int *p,int size)
{
int i;
int sum,ans;
sum=0;
ans=maxsumline(p,size);
for (i=0;i<size;i++)
{
sum+=p[i];
p[i] = -p[i];
}
if ((sum+maxsumline(p,size))>ans)
{
return (sum+maxsumline(p,size));
}
else return ans;
}
int maxsumblock(int a[],int n,int m,int cycle,int expand)
{
int i,j,k,tmp,totalmax=0,start;
int sum[32][32];
int t[32];
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
if (i!=0)
{
sum[i][j]=sum[i-1][j]+a[i*m+j];
}
else
{
sum[i][j]=a[i*m+j];
}
}
}
for (i=0;i<n;i++)
{
for (j=0;j<=i;j++)
{
for (k=0;k<m;k++)
{
t[k] = (j==0)?0:-sum[j-1][k];
t[k] +=sum[i][k];
}
tmp = cycle?maxsumcycle(t,m):maxsumline(t,m);
if (tmp>totalmax)
{
totalmax= tmp;
}
if (expand)
{
for (k=0;k<m;k++)
{
t[k]=sum[n-1][k]-sum[i][k]+sum[j][k];
// printf("%d ",t[k]);
}
//printf("\n");
tmp = cycle?maxsumcycle(t,m):maxsumline(t,m);
if (tmp>totalmax)
{
totalmax= tmp;
}
}
}
}
return totalmax;
}
#endif // ORIGINAL_H_INCLUDED
main.c:
#include "original.h"
#include <stdio.h>
int m,n,a[1024];
void init(int p)
{
int i,j;
FILE * fin;
char t[10];
t[0]=p+48;
t[1]=0;
strcat(t,"input.txt");
fin = fopen(t,"r");
fscanf(fin,"%d%d",&n,&m);
for (i=0;i<n;i++)
{
for (j=0;j<m;j++)
{
fscanf(fin,"%d",&a[i*m+j]);
}
}
}
int main(int argc,char * argv[])
{
int i,p,j,cycle=0,expand=0,amorphous=0;
for (i=1;i<argc;i++)
{
printf("%s\n",argv[i]);
if (argv[i][1]=='v')
{
expand=1;
}
if (argv[i][1]=='h')
{
cycle=1;
}
if (argv[i][1]='a')
{
amorphous=1;
}
}
printf("%d\n",expand);
for (p=0;p<10;p++)
{
init(p);
printf("%d\n",maxsumblock(a,n,m,cycle,expand));
}
return 0;
}
test.c:
#include <stdio.h>
#include <string.h>
int main()
{
FILE * fout;
char s[10];
int i,j,k,t=21318,m=233;
for (i=0;i<10;i++)
{
sprintf(s,"%d",i);
strcat(s,"input.txt");
printf("%s",s);
fout=fopen(s,"w");
fprintf(fout,"32 32\n");
for (j=0;j<32;j++)
{
for (k=0;k<32;k++)
{
m=(m*m)%t;
if (m%10<5)
{
fprintf(fout,"-");
}
fprintf(fout,"%d ",m);
}
fprintf(fout,"\n");
}
}
}
#ifndef TREAP_H_INCLUDED
#define TREAP_H_INCLUDED
typedef struct Node {
int data;
long k;
struct Node *left,*right,*parent;
} NODE ;
typedef struct {
NODE *head;
} BST;
NODE * Search(NODE *root, int x)
{
while (root && root->data!=x)
{
if (root->data>x)
root = root->left;
else
root = root->right;
}
return root;
}
void Insert(BST *t, int x ,int w)
{
NODE *node,*child,*parent,*root;
root = t->head;
node = root;
child = root;
while (node && child)
{
if (node->data==x)
child = NULL;
else
{
parent = node;
if (node->data>x)
node = node->left;
else
node = node->right;
}
}
if (child)
{
child = (NODE *)malloc(sizeof(NODE));
child->left = child->right = NULL;
child->k = w;
child->data = x;
child->parent = parent;
if (parent->data>x)
parent->left = child;
else
parent->right = child;
node = child;
while (node->parent->parent && node->k<node->parent->k)
{
parent = node->parent;
if (node->data<parent->data)
{
parent->left = node->right;
if (node->right)
{
parent->left->parent = parent;
}
node->right = parent;
if (parent->data<parent->parent->data)
parent->parent->left = node;
else
parent->parent->right = node;
}
else
{
parent->right = node->left;
if (node->left)
{
parent->right->parent = parent;
}
node->left = parent;
if (parent->data<parent->parent->data)
{
parent->parent->left = node;
}
else
{
parent->parent->right = node;
}
}
node->parent = parent->parent;
parent->parent = node;
}
if (node->parent==root && node->k<root->k)
{
if (node->data<root->data)
{
root->left = node->right;
if (node->right)
root->left->parent = root;
node->right = root;
}
else
{
root->right = node->left;
if (node->left)
root->right->parent = root;
node->left = root;
}
root->parent = node;
node->parent = NULL;
t->head = node;
}
}
return ;
}
void Delete(BST *t,int x)
{
NODE *node,*parent,*node1,*parent1,*root;
int temp;
root = t->head;
node = root;
while (node && node->data!=x)
{
parent = node;
if (node->data>x)
node = node->left;
else
node = node->right;
}
if (!node)
return;
if (node!=root)
{
node->k = 1000000;
while (node->left || node->right)
{
if (node->left)
{
node1 = node->left;
node->left = node1->right;
if (node1->right)
node1->right->parent = node;
}
else
{
node1 = node->right;
node->right = node1->left;
if (node1->left)
node1->left->parent = node;
}
if (node->parent->data>node->data)
node->parent->left = node1;
else
node->parent->right = node1;
node1->parent = node->parent;
node->parent = node1;
}
if (node->data<node->parent->data)
node->parent->left = NULL;
else
node->parent->right = NULL;
free(node);
}
return ;
}
void Init(BST *t, int x ,int w)
{
t->head = (NODE *)malloc(sizeof(NODE));
t->head->left = t->head->right = NULL;
t->head->data = x;
t->head->k = w;
t->head->parent = NULL;
return ;
}
void dfs(NODE *root)
{
if (root)
{
dfs(root->left);
printf("%d ",root->data);
dfs(root->right);
}
return ;
}
#endif // TREAP_H_INCLUDED