2020年09月 HNUCM-OJ算法分析与设计作业10

@ZHANGQIANYI2020
@[TOC](HNUCM-OJ 跟奥巴马一起编程,最长公共子序列问题(LCS)之动态规划法,最长公共子序列问题(LCS)-构造LCS,牛牛的字符串,最大子段和,Max Sum)

问题 A: 跟奥巴马一起编程

(时间限制: 1 Sec 内存限制: 128 MB)

题目描述:

美国前总统奥巴马不仅呼吁所有人都学习编程,甚至以身作则编写代码,成为美国历史上首位编写计算机代码的总统。
2014年底,为庆祝“计算机科学教育周”正式启动,奥巴马编写了很简单的计算机代码:在屏幕上画一个正方形。现在你也跟他一起画吧!

输入:

多组输入,每组数据一行,每行给出正方形边长N(3<=N<=20)和组成正方形边的某种字符C,间隔一个空格。

输出:

输出由给定字符C画出的正方形。但是注意到行间距比列间距大,所以为了让结果看上去更像正方形,我们输出的行数实际上是列数的50%(四舍五入取整)。
每组数据后空一行

样例输入:

10 a

样例输出:

aaaaaaaaaa
a        a
a        a
a        a
aaaaaaaaaa

参考答案:

import java.util.Scanner;

public class Main {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()) {
			int n=sc.nextInt();
			String s=sc.next();
			char c=s.charAt(0);
			int loop=(int)(n/2.0+0.5);
			for(int i=0;i<loop;i++){
				for(int j=0;j<n;j++){
					if(i==0||i==loop-1){
						System.out.print(c);
					}else{
						if(j==0||j==n-1){
							System.out.print(c);
						}else{
							System.out.print(" ");
						}
					}
				}
		        System.out.print("\n");
		    }
		}
	}
}

问题 B: 最长公共子序列问题(LCS)之动态规划法

(时间限制: 1 Sec 内存限制: 128 MB)
题目描述:

使用动态规划算法求解两个序列的最长公共子序列的长度。

输入:

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

输出:

两个序列的最长公共子序列的长度。

样例输入:

ACBCDABD
ABDCABA

样例输出:

5

参考答案:

import java.util.Scanner;

public class Main {
	public static int length(char char1[],char char2[]) {
		int m=char1.length-1;
		int n=char2.length-1;
		int a[][]=new int[m][n];
		int b[][]=new int[m][n];
		for(int i=0;i<n;i++) {
			a[0][i]=0;
		}
		for(int i=1;i<m;i++) {
			a[i][0]=0;
		}
		for(int i=1;i<m;i++)
			for(int j=1;j<n;j++) {
				if(char1[i]==char2[j]) {
					a[i][j]=a[i-1][j-1]+1;
					b[i][j]=1;
				}
				else if(a[i-1][j]>=a[i][j-1]) {
					a[i][j]=a[i-1][j];
					b[i][j]=2;
				}
				else {
					a[i][j]=a[i][j-1];
					b[i][j]=3;
				}
			}
		return a[m-1][n-1];
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()) {
			String s1=sc.nextLine();
			String s2=sc.nextLine();
			char char1[]=s1.toCharArray();
			char char2[]=s2.toCharArray();
			System.out.println(length(char1,char2)+1);
		}
	}
}

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

(时间限制: 1 Sec 内存限制: 128 MB)

题目描述:

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

输入:

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

输出:

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

样例输入:

acdbxx
ccdxx

样例输出:

cdxx

参考答案:

import java.util.Scanner;

public class Main {
	public static int length(char ch1[],char ch2[],int b[][]) {
		int m=ch1.length;
		int n=ch2.length;
		int c[][]=new int[m+1][n+1];
		for(int i=1;i<m;i++) {
			c[i][0]=0;
		}
		for(int i=0;i<n;i++) {
			c[0][i]=0;
		}
		for(int i=1;i<=m;i++)
			for(int j=1;j<=n;j++) {
				if(ch1[i-1]==ch2[j-1]) {
					c[i][j]=c[i-1][j-1]+1;
					b[i][j]=1;
				}
				else if(c[i-1][j]>=c[i][j-1]) {
					c[i][j]=c[i-1][j];
					b[i][j]=2;
				}
				else {
					c[i][j]=c[i][j-1];
					b[i][j]=3;
				}
			}
		return c[m][n];
	}
	public static void lcs(int i,int j,char ch1[],int b[][]) {
		if(i==0||j==0)
			return;
		if(b[i][j]==1) {
			lcs(i-1,j-1,ch1,b);
			System.out.print(ch1[i-1]);
		}else if(b[i][j]==2) {
			lcs(i-1,j,ch1,b);
		}else {
			lcs(i,j-1,ch1,b);
		}
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()) {
			String s1=sc.nextLine();
			String s2=sc.nextLine();
			char ch1[]=s1.toCharArray();
			char ch2[]=s2.toCharArray();
			int m=ch1.length;
			int n=ch2.length;
			int b[][]=new int[m+1][n+1];
			length(ch1,ch2,b);
			//System.out.println(length(ch1,ch2,b));
			lcs(m,n,ch1,b);
		}
	}
}

问题 D: 牛牛的字符串

(时间限制: 1 Sec 内存限制: 128MB)

题目描述:

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

输入:

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

输出:

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

样例输入:

abede
abgde

样例输出:

2

参考答案:

import java.util.Scanner;

public class Main {
	public static int maxpublicstring(char[] ch1,char[] ch2) {
		int m=ch1.length;
		int n=ch2.length;
		int max=0;
		int a[][]=new int[m+1][n+1];
		for(int i=0;i<=m;i++)
			for(int j=0;j<=n;j++) {
				a[i][j]=0;
			}
		for(int i=1;i<=m;i++)
			for(int j=1;j<=n;j++) {
				if(ch1[i-1]==ch2[j-1]) {
					a[i][j]=a[i-1][j-1]+1;
				}
			}
		for(int i=1;i<=m;i++)
			for(int j=1;j<=n;j++) {
				if(a[i][j]>max) {
					max=a[i][j];
				}
			}
		return max;
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()) {
			String s1=sc.nextLine();
			String s2=sc.nextLine();
			char[] ch1=s1.toCharArray();
			char[] ch2=s2.toCharArray();
			System.out.println(maxpublicstring(ch1,ch2));
		}
	}
}

问题 E: 最大子段和

(时间限制: 1 Sec 内存限制: 128MB)

题目描述:

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

输入:

每组输入包括两行,第一行为序列长度n,第二行为序列。

输出:

输出字段和的最大值。

样例输入:

5
-1 0 1 2 3

样例输出:

6

参考答案:

import java.util.Scanner;

public class Main {
	public static int max(int a[]) {
		int sum=0,max=0;
		for(int i=0;i<a.length;i++) {
			if(sum>=0) {
				sum+=a[i];
			}else {
				sum=0;
			}
			if(sum>max) {
				max=sum;
			}
		}
		return max;
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()) {
			int n=sc.nextInt();
			int a[]=new int[n];
			for(int i=0;i<n;i++) {
				a[i]=sc.nextInt();
			}
			System.out.println(max(a));
		}
	}
}

问题 F: Max Sum

(时间限制: 1 Sec 内存限制: 128MB)

题目描述:

给你一个序列 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)。

样例输入:

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

样例输出:

Case 1:
14 1 4
Case 2:
7 1 6

参考答案:

import java.util.Scanner;

public class Main {
	public static void Maxmum(int a[]) {
		int sum=0,maxsum=0;
		int temp=0,left=0,right=0;
		for(int i=0;i<a.length;i++) {
			if(sum>=0) {
				sum+=a[i];
			}else {
				sum=0;
				temp=i;
			}
			if(sum>maxsum) {
				maxsum=sum;
				left=temp+1;
				right=i+1;
			}
		}
		System.out.println(maxsum+" "+left+" "+right);
	}
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		while(sc.hasNext()) {
			int n=sc.nextInt();
			int x=1;
			while(x<=n){
				int n1=sc.nextInt();
				int a[]=new int[n1];
				for(int i=0;i<n1;i++) {
					a[i]=sc.nextInt();
				}
				System.out.println("Case "+x+":");
				Maxmum(a);
				++x;		
			}			
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值