题目--求一个数组的最大子数和和最大子数组 及 判断上三角矩阵
2019年春季学期第三周作业:
第一题:
给定一个整数数组(包含正负数),找到一个具有最大和的子数组,返回其最大的子数组的和。
例如:[1, -2, 3, 10, -4, 7, 2, -5]的最大子数组为[3, 10, -4, 7, 2]
输入:
请建立以自己英文名字命名的txt文件,并输入数组元素数值,元素值之间用逗号分隔。
输出
在不删除原有文件内容的情况下,将最大子数组以及子数组的和写入文件。
关于这个题目,我先用C++把解题的算法写了出来,先发解题算法,便于理解,接下来再发利用文件输入输出后的整段代码。
代码1:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int main (int argc,const char * argv[]) 4 { 5 int arr[100];//先定义一个整形数组 6 int n,t,x;//t是最大子数和数组终止下标,X是起始下标 7 cin>>n;//输入数组元素数量 8 for(int i=0;i<n;i++)cin>>arr[i];//赋值 9 int ans=0,maxs=0;//定义一个字数和,和最大字数和 10 for(int i=0;i<n;i++)//遍历所有元素 11 { 12 ans+=arr[i];//累加每个元素 13 if(ans>maxs){t=i;maxs=ans;}//如果ans大于maxs,证明此时还是一个连续的最大和子数组,并且用maxs标记该值 14 if(ans<0){ans=0;x=i+1;}//如果ans小于0,则证明此时一定小于之前的子数和,直接从i+1个下标开始找下一个最大子数和数组 15 } 16 for(int i=x;i<=t;i++)//输出连续的最大子数和数组 17 cout<<arr[i]<<" "; 18 return 0; 19 }
下面这段代码是用C语言来利用文件完成输入输出,并且将需要的数值写入文件:(由于解题算法代码中已解释,该处代码简单标注一下,不多做解释)
1 #include<bits/stdc++.h> 2 3 #define MAXN 10000 4 int main ( int argc , const char * argv[]) 5 { 6 FILE * FP; 7 ((FP=fopen("D:\\zdzsh.txt","a+"))==NULL)?printf("fail\n"):printf("OK!\n"); 8 int arrs[MAXN],n; 9 scanf("%d",&n); 11 for(int i=0;i<n;i++){ 12 fscanf(FP,"%d,",&arrs[i]);//从文件读入整形数值和用来分离的逗号 13 } 14 int ans=0,maxs=0,t,x; 15 for(int i=0;i<n;i++) 16 { 17 ans+=arrs[i]; 18 if(ans>maxs){t=i;maxs=ans;} 19 if(ans<0){ans=0;x=i+1;} 20 } 21 for(int i=0;i<n;i++)printf("%d ",arrs[i]); 22 printf("\n"); 23 24 FP=fopen("D:\\zdzsh.txt","a+");//由于直接从文件读入数据,文件指针需要重置到最前方才能继续写入数据 25 fprintf(FP,"\n"); 26 for(int i=x;i<=t;i++){printf("%d ",arrs[i]);fprintf(FP,"%d ",arrs[i]);} 27 printf("\n%d",maxs); 28 fprintf(FP,"\n%d",maxs); 29 30 fclose(FP); 31 return 0; 32 }
设计思路
本题调试过程中遇到的问题及解决方法
由于之前文件指针一直没有重置,导致反复试无法将数据输入至文件当中.只需再次输入绝对路径重置文件指针即可。
运行结果截图
第二题:
7-1 判断上三角矩阵 (15 分)
上三角矩阵指主对角线以下的元素都为0的矩阵;主对角线为从矩阵的左上角至右下角的连线。
本题要求编写程序,判断一个给定的方阵是否上三角矩阵。
输入格式:
输入第一行给出一个正整数T,为待测矩阵的个数。接下来给出T个矩阵的信息:每个矩阵信息的第一行给出一个不超过10的正整数n。随后n行,每行给出n个整数,其间以空格分隔。
输出格式:
每个矩阵的判断结果占一行。如果输入的矩阵是上三角矩阵,输出“YES”,否则输出“NO”。
输入样例:
2 3 1 2 3 0 4 5 0 0 6 2 1 0 -8 2
输出样例:
YES
NO
本题目比较容易,只要不粗心,一般一遍过..注意需要遍历的范围即可。
代码:
1 #include <bits/stdc++.h> 2 #define MAXN 101 3 using namespace std; 4 int num_jz[MAXN][MAXN]={0};//初始化二维数组 5 int main(int argc,const char * argv[]) 6 { 7 int T,n; 8 cin>>T;//T组数据 9 while(T--){ 10 int flag=0; 11 cin>>n;//n行n列 12 for(int i=0;i<n;i++){ 13 for(int j=0;j<n;j++){ 14 cin>>num_jz[i][j]; 15 } 16 } 17 for(int i=0;i<n;i++){ //遍历范围 18 for(int j=0;j<i;j++){ 19 if(num_jz[i][j]!=0){flag=1;break;} 20 } 21 } 22 if(flag==0)cout<<"YES"<<endl; 23 else cout<<"NO"<<endl; 24 } 25 return 0; 26 }
设计思路
本题调试过程中遇到的问题及解决方法
遍历范围出现问题,遍历超出了所需要判断的范围。其余无大问题。
运行结果截图
自我评价:此次题目难度不是很高,但写的过程中还有很多粗心的地方,导致一些简单的地方卡住,还是希望下次自己能认真点写...
学习总结:
学习总结: | 存在的问题 | 心得 | 完成作业消耗时间 | 本周学习内容 |
对文件读取数据的运用不是很熟练 | 多去看关于刷题的书籍,有助于提高自己写题能力,实在不会的可以参考大佬的代码,加以自己理解之后去默写几遍 | 半小时左右 | 文件输入,BFS,DFS,PARTITION算法及简单的贪心算法 |