山东大学计算机导论与程序设计基础限时测试二和作业二

A : 最大子数组和

题目描述

给你一个整数数组 nums ,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组 是数组中的一个连续部分。

输入格式

共 2 行数。

第一行为数组长度n。

对于测试点 1-12:0<n≤1000

对于测试点 13-14:10000<n≤20000

对于测试点 15:100000<n≤200000

第二行为 n 个数 m。

对于测试点 1-12:−1000≤m≤1000

对于测试点 13-15:−10000≤m≤10000

输出格式

一个数,为最大的子数组和。

Hint

观察数据范围 n 可以发现题目的分数区间分为了三部分

时间复杂度为 O(n3) 时可以通过测试点 1-12

时间复杂度为 O(n2) 时可以通过测试点 1-14

时间复杂度为 O(n) 时可以通过测试点 1-15

测试点 15 仅占 1 分,无需在此浪费太长时间,喜欢挑战的同学可以花一些心思优化。

可能用到的关键词:前缀和,动态规划

完整答案代码

#include<stdio.h>
int max(int m,int n)
{
	return m>n?m:n;
}
int main()
{
	int a;
	scanf("%d",&a);
	int x[a];
	int i;
	for(i=0;i<a;i++)
	{
		scanf("%d",&x[i]);
	}
	int sum[1000001];
	int maxn;
	sum[0]=x[0];
	maxn=sum[0];
	for(i=1;i<a;i++)
	{
		sum[i]=max(sum[i-1]+x[i],x[i]);
		maxn=max(sum[i],maxn);
	}
	printf("%d",maxn);
}

B : 字符串乘法

题目描述

给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。

输入格式

共 4 行数。

第一行为 num1 长度n

第二行为字符串 num1

第三行为 num2 长度m

第四行为字符串 num2

输出格式

一个字符串,为两个字符串的乘积

数据范围

对于数据点 1,2:1<n,m<5

对于数据点 3,4,5:5≤n,m≤10

对于剩余数据点:10≤n,m≤20

完整答案代码

#include<stdio.h>
int main()
{
	int n,m;
	char num1[1001],num2[1001];
	scanf("%d\n%s%d\n%s",&n,num1,&m,num2);
	int a[2002]={0};
	int i,j;
	for(i=0;i<n;i++){
		for(j=0;j<m;j++){
			a[i+j+1]+=(num1[i]-'0')*(num2[j]-'0');
		}
	}
	for(i=n+m-1;i>0;i--){
		if(a[i]>9){
			int t;
			t=a[i]%10;
			a[i-1]+=a[i]/10;
			a[i]=t;
		}
	}
	if(a[0]==0){
		for(i=1;i<n+m;i++){
			printf("%d",a[i]);
		}	
	}else{
		for(i=0;i<n+m;i++){
			printf("%d",a[i]);
		}
	}
	return 0;
}

A : 谁笑到最后

题目描述

我们规定,当两个数a和b进行“战斗“时,数值大的数胜利,而数值小的数移出数组,如果两个数大小相同,则同时移出数组。

给出n∗m个正整数。

现在让这m组中的n个正整数进行挑战赛,从第 1 个数开始向后面的数两两进行“战斗”,胜者将拥有和下一个数战斗的资格,直到这n个数只剩下 1 个或 0 个(决赛时大小相同)为止。

然后再让这m组中的胜者按组编号从小到大排序,从第 1 个数开始往后依次“战斗”,直到这些数只剩下 1 个或 0 个(决赛时大小相同)为止。

输出胜利的数,如果没有胜利的数,则输出 -1

输入格式

第 1 行为m,n (0<n<1000,0<m<100),代表共有m组,每组n个数。

接下来有m行,每行有n个正整数,均小于 10000。

输出格式

1 个整数,如果有胜利的数则输出该数,如果没有胜利的数,则输出 -1

完整答案代码

#include<stdio.h>
int main()
{
	int m,n;
	scanf("%d%d",&m,&n);
	int a[m][n];
	int i,j;
	
	for(i=0;i<m;i++){
		for(j=0;j<n;j++){
			scanf("%d",&a[i][j]);
		}
	}
	for(i=0;i<m;i++){
		for(j=0;j<n-1;j++){
			if(a[i][j]>a[i][j+1]){
				a[i][j+1]=a[i][j];
			}else if(a[i][j]==a[i][j+1]){
				a[i][j+1]=-1;
			}
		}
	}
	for(i=1;i<m;i++){
		if(a[i][n-1]<a[i-1][n-1]){
			a[i][n-1]=a[i-1][n-1];
		}else if(a[i][n-1]==a[i-1][n-1]){
			a[i][n-1]=-1;
		}
	}
	printf("%d",a[m-1][n-1]);
	return 0;
 } 

B : 字符串浮点加法

题目描述

给定两个以字符串形式表示的非负数 num1 和 num2,这两个数不一定是整数,返回 num1 和 num2 的和,它们的和也表示为字符串形式。

输入输出的数都应符合以下规则:

  • 如果该数是整数,则字符串中不含小数点和小数部分。
  • 如果该数并非整数,则小数部分最后一位不能是 0。

输入格式

共 4 行数。

第一行为 num1 长度n

第二行为字符串 num1

第三行为 num2 长度m

第四行为字符串 num2

输出格式

一个字符串,为两个字符串的和。

数据范围

对于数据点 1,2:1<n,m<5

对于数据点 3,4:5≤n,m<10

对于数据点 5,6,7:10≤n,m<15

对于剩余数据点:15≤n,m≤25

完整答案代码

#include<stdio.h>

int main()
{
	int n,m;
	char n1[10001],n2[10001];
	scanf("%d\n%s%d\n%s",&n,n1,&m,n2);
	int l1=n;
	int l2=m;
	int z1[10001]={0},z2[10001]={0};
	int f1[10001]={0},f2[10001]={0};
	int zl1=0,zl2=0;
	int fl1=0,fl2=0;
	int i,j,k;
	for(i=0;i<=l1;i++){
		if(n1[i]=='\0'){
			break;
		}
		if(n1[i]=='.'){
			break;
		}
		z1[i]=n1[i]-'0';
		zl1++;
	}
	for(i=0;i+zl1+1<l1;i++){
		f1[i]=n1[i+zl1+1]-'0';
		fl1++;
	}
	for(i=0;i<=l2;i++){
		if(n2[i]=='\0'){
			break;
		}
		if(n2[i]=='.'){
			break;
		}
		z2[i]=n2[i]-'0';
		zl2++;
	}
	for(i=0;i+zl2+1<l2;i++){
		f2[i]=n2[i+zl2+1]-'0';
		fl2++;
	}
	int fl3=1,zl=1;
	int fl=(fl1>fl2)?fl1:fl2;
	int f[10001]={0},z[10001]={0};
	
	for(i=fl-1,j=fl-1;i>0&&j>0;i--){
		f[j]+=f1[i]+f2[i];
		if(f[j]>9){
			int t;
			t=f[j]%10;
			f[j-1]+=f[j]/10;
			f[j]=t;
		}
		j--;
		fl3++;	
	}
	f[0]=f[0]+f1[0]+f2[0];
	if(f[0]>9){
		int t;
		t=f[0]%10;
		z[0]+=f[0]/10;
		f[0]=t;
	}
	for(i=zl1-1,j=zl2-1,k=0;i>=0||j>=0;i--,j--){
		if(i>=0&&j>=0){
			z[k]+=z1[i]+z2[j];
		}else if(i>=0&&j<0){
			z[k]+=z1[i];
		}else if(i<0&&j>=0){
			z[k]+=z2[j];
		}
		if(z[k]>9){
			int t;
			t=z[k]%10;
			z[k+1]+=z[k]/10;
			z[k]=t;
		}
		k++;
		zl++;
	}
	int o=fl3;

	for(i=fl3-1;f[i]==0&&i>=0;i--){
		o--;
	}
	
	if(o==0){
		if(z[zl-1]==0){
			for(i=zl-2;i>=0;i--){
				printf("%d",z[i]);
			}
		}else{
			for(i=zl-1;i>=0;i--){
				printf("%d",z[i]);
			}
		}
	}else{
		if(z[zl-1]==0){
			for(i=zl-2;i>=0;i--){
				printf("%d",z[i]);
			}
		}else{
			for(i=zl-1;i>=0;i--){
				printf("%d",z[i]);
			}
		}
		printf(".");
		for(i=0;i<o;i++){
			printf("%d",f[i]);
		}
	}
	return 0;
}

如能打赏,不胜感激[叩谢]。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值