【Java】蓝桥杯 —— 算法提高(一)

  • 蓝桥杯1111 算法提高 Torry的困惑(提高型)(素数筛)
  • 蓝桥杯1114 算法提高 最小乘积(提高型)(贪心)
  • 蓝桥杯1127 算法提高 矩阵乘方(递归)
  • 蓝桥杯1128 算法提高 夺宝奇兵(动态规划)
  • 蓝桥杯1131 算法提高 格子位置(模拟)
  • 蓝桥杯1137 算法提高 质因数(质因数分解)
  • 蓝桥杯1142 算法提高 计算整数因子(质因数分解)
  • 蓝桥杯1147 算法提高 寻找三位数(模拟)
  • 蓝桥杯1149 算法提高 利息计算(模拟)
  • 蓝桥杯1203 算法提高 彩票(模拟)


蓝桥杯1111 算法提高 Torry的困惑(提高型)(素数筛)

原题链接:算法提高 Torry的困惑(提高型)

  • 思路: 这道题是提高型的,所以势必在时间多了限制,素数筛不能用一般的了。但是这道题好奇怪,我写了埃氏筛法模板,没过,错了好多遍,不知道是数组大小的问题还是其他什么的。然后改为下面这样的写法,居然过了。。。

Code:

import java.util.Scanner;
public class Main {
	static int[] vis = new int[2000000];
	static void IsPrime() { 
		for(int i = 2; i * i < 2000000; i++) {
	        if(vis[i] == 1)
	            continue;
	        for(int j = i * i; j < 2000000; j = j + i)
	            vis[j] = 1;
	    }
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		IsPrime();
		long ans=1;
		for(int i=2,cnt=0;cnt<n;i++) {
			if(vis[i]==0) {
				ans=ans*i%50000;
				cnt++;
			}
		}
		System.out.println(ans);
	}
}


蓝桥杯1114 算法提高 最小乘积(提高型)(贪心)

原题链接:算法提高 最小乘积(提高型)

  • 思路: 简单贪心题。把两组数从小到大排序,然后第一组数从头到尾的数依次乘以第二组数从尾到头的数并累加即可。

Code:

import java.util.Arrays;
import java.util.Scanner;
public class Main {
	static int[] a = new int[1010];
	static int[] b = new int[1010];
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin = new Scanner(System.in);
		int t = cin.nextInt(); 
		while(t-- >0) {
			int n = cin.nextInt();
			for(int i=0;i<n;i++)
				a[i] = cin.nextInt();
			for(int i=0;i<n;i++)
				b[i] = cin.nextInt();
			Arrays.sort(a,0,n);
			Arrays.sort(b,0,n);
			int ans=0;
			for(int i=0;i<n;i++) 
				ans+=a[i]*b[n-i-1];
			System.out.println(ans);
		}
	}
}


蓝桥杯1127 算法提高 矩阵乘方(递归)

原题链接:算法提高 矩阵乘方

  • 思路: 递归题目,把 b 的三种情况列出来,不断递归。

Code:

import java.util.Scanner;
public class Main {
	static void square(int a[], int t[], int m) {
		int x1,x2,x3,x4;
		x1=a[1]*t[1]+a[2]*t[3];
		x2=a[1]*t[2]+a[2]*t[4];
		x3=a[3]*t[1]+a[4]*t[3];
		x4=a[3]*t[2]+a[4]*t[4];
		a[1]=x1%m; a[2]=x2%m;
		a[3]=x3%m; a[4]=x4%m;
	}
	static void pown(int a[], int b, int m) {
		if(b==0) {
			a[1]=1%m;a[2]=0%m;
			a[3]=0%m;a[4]=1%m;
		}else if(b%2==0) {
			pown(a,b/2,m);
			square(a,a,m);
		}else if(b%2==1){
			int[] t = new int[10];
			for(int i=1;i<=4;i++)
				t[i]=a[i];
			pown(a,b-1,m);
			square(a,t,m);
		}
	}
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int[] a = new int[10];
		int b = cin.nextInt();
		int m = cin.nextInt();
		for(int i=1;i<=4;i++)
			a[i]=cin.nextInt();
		pown(a,b,m);
		for(int i=1;i<=4;i++) {
			System.out.print(a[i]+" ");
			if(i==2 || i==4)	System.out.println();
		}
	}
}


蓝桥杯1128 算法提高 夺宝奇兵(动态规划)

原题链接:算法提高 夺宝奇兵

  • 思路: 经典动态规划问题,与01背包类似,就是走与不走的问题,从最后一行不断往前面走。

Code:

import java.util.Scanner;
public class Main {
	static int[][] dp = new int[105][105];
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		for(int i=1;i<=n;i++)
			for(int j=1;j<=i;j++)
				dp[i][j]=cin.nextInt();
		for(int i=n-1;i>=1;i--) 
			for(int j=1;j<=i;j++) 
				dp[i][j]=Math.max(dp[i+1][j], dp[i+1][j+1])+dp[i][j];
		System.out.println(dp[1][1]);
	}
}


蓝桥杯1131 算法提高 格子位置(模拟)

原题链接:算法提高 格子位置

  • 思路: 简单模拟题,直接暴力即可。

Code1: 我的做法,直接暴力,代码量多。先输出同行和同列的情况,再用两个数组分别标记从左上角到右下角和从左下角到右上角的同对角线所在位置。

import java.util.Scanner;
public class Main {
	static int[][] vis1 = new int[25][25];
	static int[][] vis2 = new int[25][25];
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		int x = cin.nextInt();
		int y = cin.nextInt();
		for(int i=1;i<=n;i++) {
			for(int j=1;j<=n;j++) {
				if(i==x && j==y) {
					int a=x,b=y;
					while(true) {
						vis1[a][b]=1;
						a--;b--;
						if(a<1||b<1)	break;
					}
					a=x;b=y;
					while(true) {
						a++;b++;
						if(a>n||b>n)	break;
						vis1[a][b]=1;
					}
					int c=x,d=y;
					while(true) {
						vis2[c][d]=2;
						c++;d--;
						if(c>n||d<1)	break;
					}
					c=x;d=y;
					while(true) {
						c--;d++;
						if(c<1||d>n)	break;
						vis2[c][d]=2;
					}
				}
			}
		}
		for(int j=1;j<=n;j++)
			System.out.print("("+x+","+j+")");
		System.out.println();
		for(int i=1;i<=n;i++)
			System.out.print("("+i+","+y+")");
		System.out.println();
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(vis1[i][j]==1)
					System.out.print("("+i+","+j+")");
		System.out.println();
		for(int i=n;i>=1;i--)
			for(int j=1;j<=n;j++)
				if(vis2[i][j]==2)
					System.out.print("("+i+","+j+")");
		System.out.println();
	}

}


Code2: 简单做法。先输出同行和同列的位置,然后从左上角到右下角的情况,如果横纵坐标与所给点横纵坐标距离相同即符合。从左下角到右上角,如果横纵坐标与所给点横纵坐标距离互为相反数即符合。

import java.util.Scanner;
public class Main {
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		int x = cin.nextInt();
		int y = cin.nextInt();
		for(int j=1;j<=n;j++)
			System.out.print("("+x+","+j+")");
		System.out.println();
		for(int i=1;i<=n;i++)
			System.out.print("("+i+","+y+")");
		System.out.println();
		for(int i=1;i<=n;i++)
			for(int j=1;j<=n;j++)
				if(i-x==j-y)
					System.out.print("("+i+","+j+")");
		System.out.println();
		for(int i=n;i>=1;i--)
			for(int j=1;j<=n;j++)
				if(i-x==-1*(j-y))
					System.out.print("("+i+","+j+")");
		System.out.println();
	}
}


蓝桥杯1137 算法提高 质因数(质因数分解)

原题链接:算法提高 质因数

  • 思路: 简单题目,直接遍历到 sqrt(n) ,如果 n 不是素数且 n 存在质数 i ,则输出该质数,同时 n/=i,此时 i-- ,为了输出所有相同的质数。

Code:

import java.util.Scanner;
public class Main {
	static boolean IsPrime(int n) {
		for(int i=2;i*i<=n;i++) {
			if(n%i==0)	return false;
		}
		return true;
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		System.out.print(n+"=");
		for(int i=2;i*i<=n && !IsPrime(n);i++) {
			if(n%i==0 && IsPrime(i)) {
				System.out.print(i+"*");
				n/=i;
				i--;
			}
		}
		System.out.println(n);
	}
}


蓝桥杯1142 算法提高 计算整数因子(质因数分解)

原题链接:算法提高 计算整数因子

  • 思路: 质因数分解,题目不难,就是有个坑,题目也没有说明,相同的质因数不要重复写出来。所以第一次只通过了 50% 的样例。

Code:

import java.util.Scanner;
public class Main {
	static boolean isprime(int x) {
		for(int i=2;i*i<=x;i++) {
			if(x%i==0)	return false;
		}
		return true;
	}
	static int[] vis = new int[100010];
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		for(int i=2;i*i<=n && !isprime(n);i++) {
			if(n%i==0 && isprime(i)) {
				if(vis[i]==0)	
					System.out.print(i+" ");
				vis[i]=1;
				n/=i;
				i--;
			}
		}
		System.out.println(n);
	}
}


蓝桥杯1147 算法提高 寻找三位数(模拟)

原题链接:算法提高 寻找三位数

  • 思路: 感觉蓝桥杯的题目也是够水的,没有样例,坑死了,没注意看题,wa 了好几次,原来题目要求不能含有0。

Code1: 我的做法就是遍历第一个数,每轮循环,把 0~9 都标记为 0,表示未用过,然后对 i,2i,3i,分别拆分,如果该位的数未用过且不是 0 ,ans++。最后如果 ans 等于 9,说明符合情况。

import java.util.Arrays;
public class Main {
	static int ans=0;
	static int[] vis = new int[10];
	static int calculate(int x) {
		if(vis[x%10]==0 && x%10!=0)
			ans++;	vis[x%10]=1;
		x/=10;
		if(vis[x%10]==0  && x%10!=0)
			ans++;	vis[x%10]=1;
		x/=10;
		if(vis[x]==0)
			ans++;	vis[x]=1;
		return ans;
	}
	public static void main(String[] args) {
		for(int i=123;i<=329;i++) {
			Arrays.fill(vis, 0);
			ans=0;
			calculate(i);
			calculate(i*2);
			calculate(i*3);
			if(ans==9)
				System.out.println(i+" "+i*2+" "+i*3);
		}
	}
}

Code2: 利用 Java 中 Set 容器不能存在重复元素的特点,把九个数都存入 Set 容器,如果最后长度为 9,且不存在 0 这个元素说明符合条件。

import java.util.HashSet;
import java.util.Set;
public class Main{
	public static void main(String[] args) {
		for(int i=123;i<=329;i++) {
			Set<Object> s = new HashSet<Object>();
			for(int j=1;j<=3;j++) {
				int t=i*j;
				while(t!=0) {
					s.add(t%10);
					t/=10;
				}
			}
			if(s.size()==9 && !s.contains(0))
				System.out.println(i+" "+i*2+" "+i*3);
		}
	}
}


蓝桥杯1149 算法提高 利息计算(模拟)

原题链接:算法提高 利息计算

  • 思路: 直接模拟,注意输出格式。

Code:

import java.util.*;
import java.math.*;
public class Main {
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		double x = cin.nextDouble();
		double y = cin.nextDouble();
		double ans = x+x*y*0.01*0.8;
		System.out.printf("%.2f",ans);
	}
}


蓝桥杯1203 算法提高 彩票(模拟)

原题链接:算法提高 彩票

  • 思路: 用数组 a[i] 表示中奖号码,数组 b[i] 表示彩票号码,数组 ans[i] 表示七种奖项的中奖人数,对每一组彩票的每一个号码,遍历一遍中奖号码,确定其中奖个数,从而确定其所中奖项。由于输出分别是特等奖、一等奖 …… 六等奖,所以数组 ans[i] 要倒着输出。

Code:

import java.util.Scanner;
public class Main {
	static int[] a = new int[10];
	static int[] b = new int[10];
	static int[] ans = new int[10];
	public static void main(String[] args) {
		Scanner cin = new Scanner(System.in);
		int n = cin.nextInt();
		for(int i=0;i<7;i++)
			a[i]=cin.nextInt();
		while(n-- >0) {
			int sum=0;
			for(int i=0;i<7;i++) {
				b[i]=cin.nextInt();
				for(int j=0;j<7;j++) {
					if(b[i]==a[j]) {
						sum++;	break;
					}
				}
			}
			ans[sum]++;
		}
		for(int i=7;i>=1;i--)
			System.out.print(ans[i]+" ");
		System.out.println();
	}
}


你可能感兴趣的:(蓝桥杯)