九韶杯部分题解代码

本文分享了编程竞赛中的解题思路和实战经验,包括数组、字符串、数学和矩阵问题的解决方法。例如,通过遍历计算6的个数,查找特定子串,实现斐波那契数列,数组全排列以及字符串处理。同时,文章还探讨了如何在二维矩阵中找到最大连续子序列和的高效算法。
摘要由CSDN通过智能技术生成

题目链接

A.6的个数

签到题,遍历一遍即可

public class Main {
	public static void main(String[] args) {
		int ans = 0;
		for(int i=1;i<=2016;i++) {
			int temp=i;
			while(temp!=0) {
				if(temp%10==6)ans++;
				temp/=10;
			}
		}
		System.out.println(ans);
	}
}

B.小明的作业

实不相瞒,我是用word文档查出来的,除了aw,其他字母用*代替,然后查,然后千万不要有小可爱沾沾自喜的然后看错题意直接输出和了。。。

C.斐波那契

用了一个公约数,需要注意的是要用long,不然会爆int。还有就是每次进行运算的时候都需要除一次公约数,不然long也会爆。

import java.math.BigInteger;
public class Main {
	public static long gcd(long m,long n) {
		if(n==0)return m;
		else return gcd(n,m%n);
	}
	public static void main(String[] args) {
		long arr[] = new long[14];
		arr[0] = 1;
		arr[1] = 1;
		for(int i=2;i<14;i++) {
			arr[i] = arr[i-1]+arr[i-2];
		}
		long fz = 1;
		long fm = 1;
		for(int i=1;i<13;i++) {
			fz = fz*arr[i]*arr[i+1]+fm;
			fm = fm*arr[i]*arr[i+1];
			long t =gcd(fz,fm);
			fz=fz/t;
			fm=fm/t;
		}
		System.out.println(fz+"/"+fm);
	}
}

D.数组重现

这个是一个全排列,之前比较迷的地方是判断升序降序段,当时没有想到数学的知识:没有极值点说明有一个单调段,有一个极值点说明有两个单调段,有两个极值点说明有三个单调段。很明显,这道题使极值点的数目<3即可。

import java.util.HashSet;
public class Main {
	public static int a[] = {2,5,3,6,3,6,7,3,7,8};
	public static HashSet<String>hs = new HashSet<>();
	public static void qpl(int k) {
		if(k>=a.length) {
			String str = "";
			for (int i = 0; i < a.length; i++) {
				str+=a[i];
			}
			StringBuilder sb = new StringBuilder();
			sb.append(""+a[0]);
			int bool = 0;//记录升序或者降序,1升-1降0平
			int x = 0;//记录极值点个数
			for(int i=1;i<a.length;i++) {
				sb.append(""+a[i]);
				if(a[i]>a[i-1]) {
					if(bool==-1) {
						x++;
//如果之前是降序且a[i]>a[i-1],说明有一个极值点
						bool=0;
//操作完成之后将bool还原为初始值
					}else bool = 1;
//如果之前不是降序,则说明没有极值点,将bool赋值为升序
				}
//下边的操作和上边一样
				if(a[i]<a[i-1]) {
					if(bool==1) {
						x++;
						bool=0;
					}else bool = -1;
				}
				
			}
//如果极值点<3则说明不超过3个单调的段,符合题意
			if(x<3)hs.add(sb.toString());
		}else {
			for(int i=k;i<a.length;i++) {
				int t = a[i];a[i]=a[k];a[k]=t;
				qpl(k+1);
				t = a[i];a[i]=a[k];a[k]=t;
			}
		}
	}
	public static void main(String[] args) {
		qpl(0);
		System.out.println(hs.size());
		//System.out.println(21456);
	}
}

F.字符串

这个要看清题意啊!!题目说了只有连续的@wyk才是有效的,所以判断有没有这个字符串就行了

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		sc.nextLine();
		int ans = 0;
		while(n-->0) {
			String s = sc.nextLine();
			if(s.contains("@wyk"))ans++;
		}
		System.out.println(ans);
	}
}

G.最强对手矩阵

这个题首先可以看出来是一个前缀和,但是二维前缀和太麻烦了,可以采用一维前缀和将每一列元素进行前缀和,然后找一个上界,找一个下界,依次遍历得出连续子序列的最大和。 类似的题有(一维的最大连续子数组的和
)和(二维的最大连续子数组的和

import java.util.Scanner;
public class Main {
//二维前缀和求最大值
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int a[][] = new int[n+1][m+1];
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=m;j++) {
				a[i][j] = sc.nextInt();
			}
		}
		int ans = Integer.MIN_VALUE;
		if(n<m) {//时间复杂度为n^2 * m
			for(int i=1;i<=n;i++) {
				for(int j=1;j<=m;j++) {
					a[i][j]+=a[i-1][j];//a数组赋值
				}
			}
			for(int i=1;i<=n;i++) {//上界
				for(int j=i;j<=n;j++) {//下界
					int s = 0;
					for(int k=1;k<=m;k++) {//列标
						if(s<=0)s=a[j][k]-a[i-1][k];
						else s+=a[j][k]-a[i-1][k];
						ans = Math.max(s,ans);
					}
				}
			}
		}else {//n>m时间复杂度为m^2*n
			int b[][] = new int[m+1][n+1];
			for(int i=1;i<=m;i++) {
				for(int j=1;j<=n;j++) {
					b[i][j]=a[j][i];//矩阵翻转
				}
			}
			for(int i=1;i<=m;i++) {
				for(int j=1;j<=n;j++) {
					b[i][j]+=b[i-1][j];
				}
			}
			for(int i=1;i<=m;i++) {//上界
				for(int j=i;j<=m;j++) {//下界
					int s = 0;
					for(int k=1;k<=n;k++) {//列标
						if(s<=0)s=b[j][k]-b[i-1][k];
						else s+=b[j][k]-b[i-1][k];
						ans = Math.max(s,ans);
					}
				}
			}
		}
		System.out.println(ans);
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值