17HNUCM计科练习8题解(最大子段和,矩阵连乘)

目录

 

问题 A: 习题7-18 日期计算

问题 B: 弟弟的作业 

问题 C: 求解n阶螺旋矩阵问题

问题 D: 最大子段和

 问题 E: 矩阵连乘问题-求最优值

问题 F: 牛牛的字符串

问题 G: 最长公共子序列问题(LCS)-构造LCS

问题 H: Max Sum


问题 A: 习题7-18 日期计算

题目描述

写一个函数,给定年、月、日,计算该日期是该年的第几天。在主函数中输入一个日期(含年、月、日),通过函数调用,得到该日期所对应这一年的第几天,并输出该数值。

输入

三个以空格分隔的整数,分别表示该日期的年、月、日。

输出

输入日期所对应这一年的第几天,一个整数,单独占一行。

样例输入 Copy

2014 3 8

样例输出 Copy

67

提示

可以采用如下函数原型

int getDays(int year, int month, int day);

 

计算过程中注意闰年。

#include
#include
using namespace std;
int getDays(int y, int m, int d){
	int flag;
	if(y%4==0&&y%100!=0||y%400==0)
         flag=1;
	else 
	     flag=0;
	int sum=0;
	--m;
	switch(m)
	{
		case 11:
		sum+=30;
		case 10:
		sum+=31;
		case 9:
		sum+=30;
		case 8:
		sum+=31;
		case 7:
		sum+=31;
		case 6:
		sum+=30;
		case 5:
		sum+=31;
		case 4:
		sum+=30;
		case 3:
		sum+=31;
		case 2:
		sum=sum+28+flag;
		case 1:
		sum+=31;
		break;
	}
	sum+=d;
	return sum;
}
int main()
{
	int y,m,d;
	while(cin>>y>>m>>d){
		int sum=getDays(y,m,d);
	cout<

 

问题 B: 弟弟的作业 

题目描述

你的弟弟刚做完了“100以内数的加减法”这部分的作业,请你帮他检查一下。每道题目(包括弟弟的答案)的格式为a+b=c或者a-b=c,其中ab是作业中给出的,均为不超过100的非负整数;c是弟弟算出的答案,可能是不超过200的非负整数,也可能是单个字符"?",表示他不会算。

输入

输入文件包含不超过100行,以文件结束符结尾。每行包含一道题目,格式保证符合上述规定,且不包含任何空白字符。输入的所有整数均不含前导0。

输出

输出仅一行,包含一个非负整数,即弟弟答对的题目数量。

样例输入 Copy

1+2=3
3-1=5
6+7=?
99-0=99

样例输出 Copy

2
#include
using namespace std;
int main()
{
	int a,b;
	char d,c;
    int flag=0;
    char s[4];
    int k=0;
	while(cin>>a>>c>>b>>d>>s){
        if(s[0]=='?')
            continue;
        else{
            for(int i=0;i

 

问题 C: 求解n阶螺旋矩阵问题

题目描述

创建n阶螺旋矩阵并输出。

输入

输入包含多个测试用例,每个测试用例为一行,包含一个正整数n(1<=n<=50),以输入0表示结束。

输出

每个测试用例输出n行,每行包括n个整数,整数之间用一个空格分割。

样例输入 Copy

4
0

样例输出 Copy

1 2 3 4
12 13 14 5
11 16 15 6
10 9 8 7
#include
using namespace std;
int main()
{
    int n;
    while(cin>>n&&n){
        int a[n][n];
        int i,j;
        memset(a,0,sizeof(a));
        int k=0;
        k=a[0][0]=1;
        int x,y;
        x=0;
        y=0;
        while(k=0&&!a[x][y-1])
                a[x][--y]=++k;
            while(x-1>=0&&!a[x-1][y])
                a[--x][y]=++k;
        }
        for(i=0;i

 

问题 D: 最大子段和

题目描述

给定n个整数(可能是负数)组成的序列a[1], a[2], a[3], …, a[n],求该序列的子段和如a[i]+a[i+1]+…+a[j]的最大值。

输入

每组输入

包括两行,第一行为序列长度n,第二行为序列。

输出

输出字段和的最大值。

样例输入 Copy

5
-1 0 1 2 3

样例输出 Copy

6
#include
#include
#include
#include
using namespace std;
int main()
{
	int n;
	while(cin>>n){
		int i;
		int a[n];
		for(i=0;i>a[i];
		}
		int dp[n];
		dp[0]=a[0];
		for(i=1;i

 问题 E: 矩阵连乘问题-求最优值

 

题目描述

使用动态规划算法求解矩阵连乘问题,输出最少乘法次数。

输入

每组数据包括两行,第一行为数组长度n,第二行为存储矩阵维数的一维数组。

输出

矩阵连乘最优计算次数。

样例输入 Copy

7
30 35 15 5 10 20 25

样例输出 Copy

15125

 

#include
#include
#include
#include
using namespace std;
int dp[105][105];
void matrixChain(int a[],int n){
    for(int i=1;i>m){
	    int a[m];
	    int i;
	    memset(dp,0,sizeof(dp));
	    for(i=0;i>a[i];
	    }
	    matrixChain(a,m);
	    cout<

问题 F: 牛牛的字符串

题目描述

牛牛有两个字符串(可能包含空格),他想找出其中最长的公共连续子串的长度,希望你能帮助他。例如:两个字符串分别为"abede"和"abgde",结果为2。

输入

每组数据包括两行,每行为一个字符串。

输出

输出最长的公共连续子串的长度。

样例输入 Copy

abede
abgde

样例输出 Copy

2
#include
using namespace std;
int main()
{
    string a,b;
	while(getline(cin,a)){
        getline(cin,b);
        int la,lb;
        la=a.length();
        lb=b.length();
        int dp[la+1][lb+1];
        int i,j;
        int M=0;
        for(i=0;iM)
                    M=dp[i][j];
            }
        }
        cout<

 

问题 G: 最长公共子序列问题(LCS)-构造LCS

题目描述

使用动态规划算法求两个序列的最长公共子序列,需构造一条最长公共子序列。

输入

每组输入包括两行,每行包括一个字符串。

输出

两个字符序列的一条最长公共子序列。(输入已确保最长公共子序列的唯一性)

样例输入 Copy

acdbxx
ccdxx

样例输出 Copy

cdxx
#include
using namespace std;
int d[105][105];
void lcs(int i,int j,string a){
    if(i==0||j==0)
        return ;
    if(d[i][j]==1){
        lcs(i-1,j-1,a);
        cout<=dp[i][j-1]){
                    dp[i][j]=dp[i-1][j];
                    d[i][j]=2;
                }
                else{
                    dp[i][j]=dp[i][j-1];
                    d[i][j]=3;
                }
            }
        }
        //cout<

 

问题 H: Max Sum

题目描述

给你一个序列 a[1],a[2],a[3]......a[n], 你要做的是求出最大字段和. 比如, 输入 6,-1,5,4,-7, 这个序列的最大字段和就是 6 + (-1) + 5 + 4 = 14.

输入

The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).

输出

每组测试用例输出两行。 
第一行是"Case #:" # 表示测试用例的序数。
第二行包括三个数字,最大子段和,以及子段的起始位置和结束位置
例如:输入数组(6,-1,5,4,-7),输出14, 1, 4,其中14表示最大子段和,1表示和最大的子段从第1个数字开始,4表示和最大的子段到第4个数字结束,即(6, -1 , 5, 4)。

 

样例输入 Copy

2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5

样例输出 Copy

Case 1:
14 1 4
Case 2:
7 1 6
//求出最大子段和以及这一段的起始位置和终点位置
#include
#include
#include
#include
using namespace std;
int main()
{
	int n,m;
	while(cin>>m){
        for(int j=1;j<=m;j++){
            cin>>n;
            int i;
            int a[n];
            for(i=0;i>a[i];
            }
            int dp[n];
            dp[0]=a[0];
            int f1,f2;
            f1=f2=0;
            int M=a[0];
            for(i=1;i=0;--i){
                M-=a[i];
                if(M==0){
                    f2=i;
                }
            }
            ++f2;
            ++f1;
            cout<

 

你可能感兴趣的:(算法学习)