2020蓝桥杯救命稻草--之救命15题

2020蓝桥杯救命稻草

第一阶段:基础知识(对标省三)
Step1:基本语法(流程,控制,循环)
(半小时内独立解决“打印图形”&“数的分解”可以跳过此Step)
(拓展:用有限变量解决“斐波那契”问题。)
Step2:JavaAPI(排序,容器,字符串,大数)
(半小时内独立解决“日志统计”&“复数幂”可以跳过此Step)
(拓展:解决“人物相关性分析”部分问题。)
第二阶段:能力提升(对标省二)
Step3:数组(前缀和,差分,简单DP)
(一小时内独立解决“最大下降矩阵”&“校门外的树”可以跳过此Step)
(拓展:解决“人物相关性分析”问题。)
Step4:函数(质数筛,汉诺塔,快速幂)
(一小时内独立解决“哥德巴赫猜想”&“大数运算”可以跳过此Step)(39级台阶)
(拓展:解决“经典汉诺塔”问题。)
第三阶段:暴力美学(对标省一)
Step5:暴力破解一(全排列,二分)
(一小时内独立解决“瓜分种数”&“分巧克力”可以跳过此Step)
Step6:暴力破解二(DFS,BFS)
(一小时内独立解决“全球变暖”&“迷宫求解”可以跳过此Step)
第四阶段:考试技巧(提升大概1~2个等级)
Step7:技巧篇(无)

  • 注:精选蓝桥思维算法15道,且有对标水准,几乎涵盖所有会用到的思想和算法,后边题目难度较大,恳请对代码指正优化

Step1:基本语法(流程,控制,循环)

1.“打印图形”

打印图形
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
小明刚学习完条件语句和循环语句,并且也打印了许多图形,比如菱形或者三角形。然后他突发奇想要打印一个六芒星,果然,他用了半小时就把六芒星给打印出来了,你能比他更快吗?小明为你加油哦!
【输入格式】
输入一行包含一个整数 n。
【输出格式】
输出一个六芒星,表示满足题意的图形。
【样例输入】
3
4
【样例输出】
   

 
  
【评测用例规模与约定】  
对于所有评测用例,1 ≤ n ≤ 20
import java.util.Scanner;
public class A_PrintSixPointStar {
    
    
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		if(n == 1)
			System.out.print('*');
		else if (n > 1 && n <= 20) {
    
    
			int i = 4 * n - 3;
			int j = 6 * n - 5;
			char arr[][] = new char[i][j];
			for(int a = 0; a < arr.length; a ++) {
    
    
				for(int b = 0; b < arr[1].length; b ++) {
    
    	
					if (a < n - 1) {
    
    
						arr[a][(3 * n - 3) - a] = '*';
						arr[a][(3 * n - 3) + a] = '*';
					}
					else if (a == n - 1 && b % 2 == 0)
						arr[a][b] = '*';
					else if (a > n - 1 && a <= 2 * n - 2) {
    
    
						arr[a][a - n + 1] = '*';
						arr[a][3 * n - 3 - a] = '*';
						arr[a][3 * n - 3 + a] = '*';
						arr[a][7 * n - 7 - a] = '*';	
					}		
					else if(a > 2 * n - 2)
						arr[a][b] = arr[4 * n - a - 4][b];
					else
						arr[a][b] = ' ';	
				}
			for (int k = 0; k < arr.length; k++) {
    
    
				for (int k2 = 0; k2 < arr[1].length; k2++)
					System.out.print(arr[k][k2]);
				System.out.println();
			}		
		}
	}
}

2.“数的分解”

 								数的分解
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
把 n分解成 3 个各不相同的正整数之和,并且要求每个正整数都不包
含数字  24,一共有多少种不同的分解方法?
注意交换 3 个整数的顺序被视为同一种方法,例如 1999+3+181999+18+3 被视为同一种。
【输入格式】
输入一行包含一个整数 n。
【输出格式】
输出一行,包含一个整数,表示满足条件的分解方法种数。
【样例输入】
2019
【样例输出】
40785
【评测用例规模与约定】
对于所有评测用例,100 ≤ n ≤ 2500
import java.util.Scanner;

public class B_TheNumberOfDecomposition {
    
    

	private static boolean judge(int s) {
    
    
		while( s > 0) {
    
    
			
			int t = s % 10;
			if(t== 2 || t== 4)
				return false;
			s /= 10;	
		}
		return true;
	}
	
	public static void main(String[] args) {
    
    
		
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int sum = 0;
		
		if(n >= 100 && n <= 2500){
    
    
			for (int i = 1; i <= n / 3 ; i++){
    
     
				for (int j = 1; j < n; j++) {
    
    
					int k = n - i - j;
					if(k > j && i < j) {
    
    
						if (judge(i) && judge(j) && judge(k))
							sum ++;
					}
				}
			}	
		}
		System.out.println(sum);		
	}
}

3.“斐波那契”

 
 斐波那契
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1。
当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少。
<此题禁止使用数组容器等数据结构>
 
【输入格式】
输入一行包含一个整数 n。
【输出格式】
输出一行,包含一个整数,表示满足条件的数的和。
【样例输入】
22
【样例输出】
7704
【评测用例规模与约定】
对于所有评测用例,1 ≤ n ≤ 1,000,000
import java.util.Scanner;

public class C_FibonacciNumber {
    
    

	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		long n = sc.nextLong();
			long a  =1;
			long b = 1;
			long t = 1;
			for (long i = 2; i < n; i++) {
    
    
				t = a;
				a += b;
				a %= 10007;
				b = t;
			}
			long result = a;
			System.out.println(result);	
	}
}

Step2:JavaAPI(排序,容器,字符串,大数)

1.“日志统计”

      日志统计
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
小明维护着一个程序员论坛。现在他收集了一份"点赞"日志,日志共有N行。其中每一行的格式是:
ts id 
表示在ts时刻编号id的帖子收到一个"赞"。 
 
现在小明想统计有哪些帖子曾经是"热帖"。如果一个帖子曾在任意一个长度为D的时间段内收到不少于K个赞,小明就认为这个帖子曾是"热帖"。 
具体来说,如果存在某个时刻T满足该帖在[T, T+D)这段时间内(注意是左闭右开区间)收到不少于K个赞,该帖就曾是"热帖"。 
 
给定日志,请你帮助小明统计出所有曾是"热帖"的帖子编号。 
【输入格式】
第一行包含三个整数N、D和K。 
以下N行每行一条日志,包含两个整数ts和id。 
 
对于50%的数据,1 <= K <= N <= 1000 
对于100%的数据,1 <= K <= N <= 100000 0 <= ts <= 100000 0 <= id <= 100000 
 
【输出格式】
按从小到大的顺序输出热帖id。每个id一行。 
 
【输入样例】
7 10 2 
0 1 
0 10   
10 10 
10 1 
9 1
100 3 
100 3 
 
【输出样例】
1 
3 
package 精选思维15;

import java.util.HashSet;
import java.util.Iterator;
import java.util.Scanner;

public class 日志统计step2 {
    
    

	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int D = sc.nextInt();
		int K = sc.nextInt();
		
		int arr[][] = new int [N][5];
		for (int i = 0; i < N; i++) {
    
    
			arr[i][0] = sc.nextInt();
			arr[i][1] = sc.nextInt();
			
		}
		for (int i = 0; i < N; i++) {
    
    
			int first =1;
			for (int j = i+1; j < N; j++) {
    
    
				if (arr[j][1]==arr[i][1]) 
					first++;
					if (j==N-1) 
						arr[i][2]=first;
			}
		}
		for (int i = 0; i < N; i++) {
    
    
			if (arr[i][2]>=K)
				arr[i][3]=1;
		}
		
		for (int i = 0; i < N; i++) {
    
    
			for (int j = i+1; j < N; j++) {
    
    
				if (arr[i][3]==1&&arr[i][1]==arr[j][1]&&arr[j][0]-arr[i][0]<D) 
					arr[i][4]=1;
			}
		}
		HashSet<Integer> ar= new HashSet<Integer>(); 
		for (int i = 0; i < N; i++) {
    
    
			if (arr[i][4]==1) {
    
    
				ar.add(arr[i][1]);
			}
		}
		
		Iterator<Integer> result = ar.iterator();
		while (result.hasNext()) {
    
    
      
			System.out.println(result.next());
		}	
	}
}

2.“复数幂”

复数幂
【问题描述】
设i为虚数单位。对于任意正整数n,(2+3i)^n 的实部和虚部都是整数。
求 (2+3i)^123456 等于多少? 即(2+3i)123456次幂,这个数字很大,要求精确表示。
 
答案写成 "实部±虚部i" 的形式,实部和虚部都是整数(不能用科学计数法表示),中间任何地方都不加空格,实部为正时前面不加正号。
(2+3i)^2 写成: -5+12i,
(2+3i)^5 的写成: 122-597i
 
 
注意:需要提交的是一个很庞大的复数,不要填写任何多余内容。
package 精选思维15;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigInteger;

public class 复数幂step2 {
    
    

	public static void main(String[] args) throws IOException {
    
    
		// TODO Auto-generated method stub
		int mi = 123456;
		BigInteger a = new BigInteger("2");
		BigInteger b = new BigInteger("3");
		BigInteger bigA;
		BigInteger bigB;
		
		for (int i = 0; i < mi-1; i++) {
    
    
			bigA =a.multiply(BigInteger.valueOf(2)).subtract(b.multiply(BigInteger.valueOf(3)));
			bigB =a.multiply(BigInteger.valueOf(3)).add(b.multiply(BigInteger.valueOf(2)));
			a = bigA;
			b = bigB;
		}
		 
		FileWriter writer = new FileWriter("第十一届蓝桥/精选思维15题/bi.text");	
		writer.write(b.compareTo(BigInteger.ZERO) == 1 ? a + "+" + b + "i" : a + "" + b + "i");
		writer.flush();
	}
}

3.“人物相关性分析”

   人物相关性分析
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
小明正在分析一本小说中的人物相关性。他想知道在小说中 Alice 和 Bob
有多少次同时出现。
更准确的说,小明定义 Alice 和 Bob“同时出现”的意思是:在小说文本
中 Alice 和 Bob 之间不超过 K 个字符。
例如以下文本:
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
假设 K = 20,则 Alice 和 Bob 同时出现了 2 次,分别是”Alice and Bob”
和”Bob. Alice”。前者 Alice 和 Bob 之间有 5 个字符,后者有 2 个字符。
注意:
1. Alice 和 Bob 是大小写敏感的,alice 或 bob 等并不计算在内。
2. Alice 和 Bob 应为单独的单词,前后可以有标点符号和空格,但是不能
有字母。例如 Bobbi 並不算出现了 Bob。
【输入格式】
第一行包含一个整数 K。
第二行包含一行字符串,只包含大小写字母、标点符号和空格。长度不超
过 1000000。
【输出格式】
输出一个整数,表示 Alice 和 Bob 同时出现的次数。
【样例输入】
20
This is a story about Alice and Bob. Alice wants to send a private message to Bob.
【样例输出】
2
【评测用例规模与约定】
对于所有评测用例,1 ≤ K ≤ 1000000
import java.util.Scanner;

public class F_TheCharacterCorrelationAnalysis {
    
    

	public static void main(String[] args) {
    
    
		
		Scanner sc = new Scanner(System.in);
		int K = sc.nextInt();
		int num = 0;
		sc.nextLine();
		String paragraph = sc.nextLine();
		
		String[] stringList ;
		stringList = paragraph.split(" ");	
		
		for (int i = 0; i < stringList.length - 1; i++) {
    
    
			int length = 0;
			if(stringList[i].equals("Alice")){
    
    
				for (int j = i + 1; j < stringList.length; j++) {
    
    
					length += 1 + stringList[j].length();
					if(length <= K + 3 && stringList[j].equals("Bob")) {
    
    
						num ++;
						break;
					}
					else if (length <= K + 4 && stringList[j].equals("Bob.")) {
    
    
						num ++;
						break;
					}
					else if(length > K)
						break;	
				}
			}
			
			else if(stringList[i].equals("Bob")) {
    
    
				for (int j = i + 1; j < stringList.length; j++) {
    
    
					length += 1 + stringList[j].length();
					if(length <= K + 5 && stringList[j].equals("Alice")) {
    
    
						num ++;
						break;
					}
					else if(length <= K + 6 && stringList[j].equals("Alice.")) {
    
    
						num ++;
						break;
					}
					else if(length > K)
						break;
				}
			}
			else if(stringList[i].equals("Alice.")){
    
    
				for (int j = i + 1; j < stringList.length; j++) {
    
    
					length += 1 + stringList[j].length();
					if(length <= K + 3 && stringList[j].equals("Bob")) {
    
    
						num ++;
						break;
					}
					else if(length <= K + 4 && stringList[j].equals("Bob.")) {
    
    
						num ++;
						break;
					}
					else if(length > K)
						break;	
				}
			}
			
			else if(stringList[i].equals("Bob.")) {
    
    
				for (int j = i + 1; j < stringList.length; j++) {
    
    
					length += 1 + stringList[j].length();
					if(length <= K + 5 && stringList[j].equals("Alice")) {
    
    
						num ++;
						break;
					}
					if(length <= K + 6 && stringList[j].equals("Alice.")) {
    
    
						num ++;
						break;
					}
					else if(length > K)
						break;
				}
			}
		}
		
		
		System.out.println(num);	
	}
}
 2020/08/28 14:31 
package 精选思维15;
import java.io.File;
import java.io.FileInputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;

public class 人物相关性分析 {
    
    

	private static String getTemplateContent() throws Exception {
    
    
		File file = new File("C:\\Users\\王小明\\Desktop\\算法蓝桥\\step2评测标准\\人物相关性分析测评标准\\data8.in");
		if(!file.exists())
			return null;
		FileInputStream inputStream = new FileInputStream(file);
		int length = inputStream.available();
		byte bytes[] = new byte[length];
		inputStream.read(bytes);
		inputStream.close();
		String str = new String(bytes, StandardCharsets.UTF_8);
		return str;
	}
	
	public static void main(String[] args) throws Exception {
    
    
		
		Scanner sc = new Scanner(System.in);
		int K = sc.nextInt();
		int num = 0;
		sc.nextLine();
		String first_paragraph = getTemplateContent();
		long start_time = System.currentTimeMillis();
		StringBuilder paragraph = new StringBuilder(first_paragraph);
		for (int i = 0; i < paragraph.length(); i++) {
    
    
			char temporary = paragraph.charAt(i);
			if(temporary == '.' || temporary == ',' || temporary == '?' || temporary == '!' || temporary == ':' || temporary == ';') {
    
    
				 {
    
    
					paragraph.insert(i, " ");
					paragraph.insert(i + 2, " ");
					i += 3;		
				}
			}
		}
		String[] stringList ;
		stringList = paragraph.toString().split(" ");

		for (int i = 0; i < stringList.length - 1; i++) {
    
    
			int length = 0;
			if(stringList[i].equals("Alice")){
    
    
				for (int j = i + 1; j < stringList.length; j++) {
    
    
					length += 1 + stringList[j].length();
					if(length <= K + 3 && stringList[j].equals("Bob")) {
    
    
						num ++;
						break;
					}
					else if(length > K)
						break;	
				}
			}
			
			else if(stringList[i].equals("Bob")) {
    
    
				for (int j = i + 1; j < stringList.length; j++) {
    
    
					length += 1 + stringList[j].length();
					if(length <= K + 5 && stringList[j].equals("Alice")) {
    
    
						num ++;
						break;
					}
					else if(length > K)
						break;
				}
			}
		}
		long end_time = System.currentTimeMillis();
		long times = (end_time - start_time) / 1000;
		System.out.println(num);
		System.out.println(times);
		
	}
}

第二阶段:能力提升(对标省二)

Step3:数组(前缀和,差分,简单DP)

1.“最大下降矩阵”

最大下降矩阵
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
我们称一个矩阵是下降矩阵,当且仅当,矩阵的每一列都是严格下降的。很显然,这个要求很苛刻,大多数矩阵都无法满足。但是显然如果消去一些行,一定可以使得这个矩阵变成下降矩阵。

    现在给出一个n行m列的矩阵,请你求出最少消去多少行,可以使得这个矩阵变为下降矩阵。
【输入格式】
输入第一行包含两个正整数n,m分别表示矩阵的行数和列数。(1<=n,m<=300)
接下来n行,每行有m个数,中间用空格隔开,每个数都小于2^31.
【输出格式】
输出一行,包含一个整数,表示最少消去的行数。
【样例输入11 3
1 2 3
【样例输出10
【样例输入23 1
3
1
2
【样例输出21
import java.util.Scanner;

public class G_TheBiggestDeclineMatrix {
    
    

	public static void main(String[] args) {
    
    

		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		sc.nextLine();
		int[][] matrix = new int[n][m];
		int[] decline = new int [n];
		for(int i = 0; i < n; i ++) {
    
    
			decline[i] = 1;
			for(int j = 0; j < m; j ++)
                       matrix[i][j] = sc.nextInt();
			sc.nextLine();
		}
		
		for(int i = 1; i < n; i ++) {
    
    
			for(int j = i - 1; j > 0; j --) {
    
    
				if(decline[i] > decline[j])
					continue;
				boolean flag = true;
				for(int k = 0; k < m; k ++) {
    
    
					if(matrix[i][k] < matrix[j][k]) {
    
    
						flag = false;
						break;
					}		
				}
				if(flag)
					decline[i] = decline[j] + 1;
			}
		}
		
		int max_decline = 0;
		for(int i = 0; i < n; i ++)
			max_decline = Math.max(max_decline, decline[i]);
		int result = n - max_decline;
		System.out.println(result);
	}
}

2.“校门外的树”

校门外的树
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
某校大门外长度为L的马路上有一排树,每两棵相邻的树之间的间隔都是1米。我们可以把马路看成一个数轴,马路的一端在数轴0的位置,另一端在L的位置;数轴上的每个整数点,即012,……,L,都种有一棵树。
由于马路上有一些区域要用来建地铁。这些区域用它们在数轴上的起始点和终止点表示。已知任一区域的起始点和终止点的坐标都是整数,区域之间可能有重合的部分。现在要把这些区域中的树(包括区域端点处的两棵树)移走。你的任务是计算将这些树都移走后,马路上还有多少棵树。
【输入格式】
第一行有两个整数:L(1 <= L <= 10000)和 M(1 <= M <= 100),L代表马路的长度,M代表区域的数目,L和M之间用一个空格隔开。接下来的M行每行包含两个不同的整数,用一个空格隔开,表示一个区域的起始点和终止点的坐标。【输出格式】
输出一行,包含一个整数,表示马路上剩余的树的数目。
【样例输入】
500 3
150 300
100 200
470 471
【样例输出】
298
【评测用例规模与约定】
对于 20% 的评测用例,区域之间没有重合的部分。
对于所有评测用例,区域之间有重合的情况。
import java.util.Scanner;

public class H_TreesOutsideTheSchoolGate {
    
    

	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int L = sc.nextInt();
		int M = sc.nextInt();
		sc.nextLine();
		
		int[][] area = new int[M][2];
		for (int i = 0; i < M; i++) {
    
    
			for (int j = 0; j < 2; j++)
				area[i][j] = sc.nextInt();
			sc.nextLine();
		}
		
		int[][] length = new int[L + 1][2];
		for (int i = 0; i <= L; i++) {
    
    
			length[i][0] = i;
			length[i][1] = 0;
		}
		
		for (int i = 0; i < M; i++)
                for (int k = area[i][0]; k <= area[i][1]; k++)
                    length[k][1] = 1;
		
		int result = 0;
		for (int i = 0; i <= L; i++) {
    
    
			if(length[i][1] == 0)
				result ++;
		}
		System.out.println(result);
	}
}

Step4:函数(质数筛,汉诺塔,快速幂)

1.“哥德巴赫猜想”

哥德巴赫猜想
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
哥德巴赫1742年给欧拉的信中哥德巴赫提出了以下猜想:任何一个≥6的偶数,都可以表示成两个奇质数之和.。但是哥德巴赫自己无法证明它,于是就写信请教赫赫有名的大数学家欧拉帮忙证明,但是一直到死,欧拉也无法证明。
 
现在你的朋友坤坤告诉你,哥德巴赫的猜想是错误的,现在坤坤告诉你一个≥6的偶数,请你告诉他组成该偶数的两个奇数。
【输入格式】
输入一行包含一个偶数 n。
【输出格式】
输出一行,包含两个整数,表示满足条件的奇数。
【样例输入】
6
【样例输出】
3 3
【评测用例规模与约定】
对于所有评测用例,6 ≤ n ≤ 1,000,000

方法1

import java.util.Scanner;

public class I_GoldbachConjecture {
    
    

	public static void main(String[] args) {
    
    
		
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		
		int middle = n / 2;
		
		int[][] arr = new int[middle][3];
		for (int i = 3; i <= middle; i++) {
    
    
			arr[i - 3][0] = i;
			arr[i - 3][1] = n - i;
		}
		for (int i = 0; i < arr.length; i++) {
    
    
			for (int j = 2; j < arr[i][0]; j++) {
    
    
				if(arr[i][0] % j != 0 && arr[i][0] - j == 1) {
    
    
					for (int k = 2; k < arr[i][1]; k++) 
						if(arr[i][1] % k != 0 && arr[i][1] - k == 1)
							arr[i][2] = 1;
				}
			}
		}
		
		for (int i = 0; i < arr.length; i++) {
    
    
			if(arr[i][2] == 1)
				System.out.println(arr[i][0] + " " + arr[i][1]);
				break;
		}
	}
}

方法2(最标准)

public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int a = sc.nextInt();
		
		for (int i = 3; i < a / 2; i += 2) {
    
    
			int j = a - i;
			if (isPrime(i) && isPrime(j)) {
    
    
				System.out.println(i + " " + j);
				break;
			}
		}
	}

	public static boolean isPrime(int i) {
    
    
        for (int j = 2; j < i - 1; j++)
            if (i % j == 0)
                return false;
        return true;
    }

2.“大数运算”

大数运算
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
坤坤刚刚得知你学会了Java的大数运算,所以坤坤决定考考你,坤坤告诉你三个正整数。X,Y,Z,表示X的Y次方对Z取模。
【输入格式】
输入一行包含三个整数 X Y Z。
【输出格式】
输出一行,包含一个整数,运算后取模的结果。
【样例输入】
2 3 1000
【样例输出】
8
【评测用例规模与约定】
对于所有评测用例,1 ≤ X,Y,Z ≤ 1,000,000
import java.math.BigInteger;
import java.util.Scanner;

public class J_LargeNumberOperation {
    
    

	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		BigInteger X = sc.nextBigInteger();
		int Y = sc.nextInt();
		BigInteger Z = sc.nextBigInteger();
		BigInteger result = X;
		
		for (int i = 0; i < Y - 1; i++) {
    
    
			result = (result.multiply(X).mod(Z));
		}
		System.out.println(result);
	}
}

3.“经典汉诺塔”

经典汉诺塔
【问题描述】
汉诺塔(Hanoi Tower),又称河内塔,源于印度一个古老传说。大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。并且规定,任何时候,在小圆盘上都不能放大圆盘,且在三根柱子之间一次只能移动一个圆盘。问应该如何操作?



【输入格式】
输入一行包含一个整数 n,表示圆盘的层数。
【输出格式】
输出圆盘的移动路径。
【样例输入】
3
【样例输出】
a->c
a->b
c->b
a->c
b->a
b->c
a->c
import java.util.Scanner;

public class K_TheClassicHanoi {
    
    

	private static void move(char A, char C) {
    
    
		System.out.println(A + "->" + C);
	}
	
	private static void hanoi(int n, char A, char B, char C) {
    
    
		if(n == 1)
			move(A, C);
		else {
    
    
			hanoi(n - 1, A, C, B);
			move(A, C);
			hanoi(n - 1, B, A, C);
		}
	}
	
	public static void main(String[] args) {
    
    
	
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		char A = 'A';
		char B = 'B';
		char C = 'C';
		
		hanoi(n, A, B, C);
	}
}

第三阶段:暴力美学(对标省一)

Step5:暴力破解一(全排列,二分)

1.“瓜分种数”

  瓜分种数
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
有n个糖果,要分给n个小朋友,请问有多少种分配方案,输出每种分配方案。
【输入格式】
输入一行包含一个整数 n。
【输出格式】
输出一行,包含一个整数,表示满足条件的方法种数。
输出每种分配方案。
【样例输入】
3
【样例输出】
6
1 2 3
1 3 2
2 1 3
2 3 1
3 1 2
3 2 1
【评测用例规模与约定】
对于所有评测用例,1 ≤ n ≤ 12
import java.util.Scanner;

public class L_DivideSpecies {
    
    

	public static int[] arr;
	static long sum;
	private static void nercous(int n) {
    
    
		if(n == arr.length - 1) {
    
    
			for (int i = 0; i <= n; i++)
				System.out.print(arr[i] + (i == n ? "" : " "));
			System.out.println();
		}else {
    
    
			for (int i = n; i < arr.length; i++) {
    
    
				int t = arr[i]; 
				arr[i] = arr[n];
				arr[n] = t;
				nercous(n + 1);
				t = arr[i];
				arr[i] = arr[n];
				arr[n] = t;
			}
		}	
	}
	
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		arr = new int[n];
		for (int i = 0; i < n; i++)
			arr[i] = sc.nextInt();
		for (int i = 0; i < n; i++)
			sum += i + 1;
		System.out.println(sum);
		nercous(0);
	}
}

2.“分巧克力”

分巧克力
时间限制: 1.0s   内存限制: 512.0MB
【问题描述】
    儿童节那天有K位小朋友到小明家做客。小明拿出了珍藏的巧克力招待小朋友们。
    小明一共有N块巧克力,其中第i块是Hi x Wi的方格组成的长方形。
 
    为了公平起见,小明需要从这 N 块巧克力中切出K块巧克力分给小朋友们。切出的巧克力需要满足:
 
    1. 形状是正方形,边长是整数 
    2. 大小相同 
 
例如一块6x5的巧克力可以切出6块2x2的巧克力或者2块3x3的巧克力。
 
当然小朋友们都希望得到的巧克力尽可能大,你能帮小Hi计算出最大的边长是多少么?
 
【输入格式】
第一行包含两个整数N和K。(1 <= N, K <= 100000) 
以下N行每行包含两个整数Hi和Wi。(1 <= Hi, Wi <= 100000)
输入保证每位小朋友至少能获得一块1x1的巧克力。  
 
【输出格式】
输出切出的正方形巧克力最大可能的边长。
 
【样例输入】
2 10 
6 5 
5 6 
 
【样例输出】
2
import java.util.Scanner;

public class M_PointsOfChocolate {
    
    

	private static void segmentation(int left, int right, int N, Integer K, int[][] Chocolate) {
    
    
		while(left <= right) {
    
    
			int middle = (left + right) / 2;
			int sum = 0;
			for (int i = 0; i < N; i++)
				sum += (Chocolate[i][0] / middle) * (Chocolate[i][1] / middle);
			if(right - left == 1) {
    
    
				System.out.println(left);
				break;
			}else if(sum < K) 
				right = middle;
			else if(sum > K)
				left = middle;	
		}
	}
	
	public static void main(String[] args) {
    
    
		Scanner sc = new Scanner(System.in);
		int N = sc.nextInt();
		int K = sc.nextInt();
		int[][] chocolate = new int[N][2];
		
		int Max_length = 0;
		for (int i = 0; i < N; i++) {
    
    
			chocolate[i][0] = sc.nextInt();
			chocolate[i][1] = sc.nextInt();
			sc.nextLine();
			int Max_middle = Math.max(chocolate[i][0], chocolate[i][1]);
			Max_length = Math.max(Max_length, Max_middle);
		}	
		
		int left = 1;
		int right = Max_length;
		segmentation(left, right, N, K, chocolate);	
	}
}

Step6:暴力破解二(DFS,BFS)

1.“全球变暖”

全球变暖
【问题描述】
你有一张某海域NxN像素的照片,"."表示海洋、"#"表示陆地,如下所示:
 
.......
.##....
.##....
....##.
..####.
...###.
.......
 
其中"上下左右"四个方向上连在一起的一片陆地组成一座岛屿。例如上图就有2座岛屿。 
 
由于全球变暖导致了海面上升,科学家预测未来几十年,岛屿边缘一个像素的范围会被海水淹没。具体来说如果一块陆地像素与海洋相邻(上下左右四个相邻像素中有海洋),它就会被淹没。 
 
例如上图中的海域未来会变成如下样子:
 
....... 
.......
.......
.......
....#..
.......
.......
 
请你计算:依照科学家的预测,照片中有多少岛屿会被完全淹没。 
 
【输入格式】
第一行包含一个整数N。  (1 <= N <= 1000) 
以下N行N列代表一张海域照片。 
 
照片保证第1行、第1列、第N行、第N列的像素都是海洋。 
 
【输出格式】
一个整数表示答案。
 
【输入样例】
7
.......
.##....
.##....
....##.
..####.
...###.
....... 
 
【输出样例】
1 
 
 
 
资源约定:
峰值内存消耗(含虚拟机) < 256M
CPU消耗  < 1000ms
 
 
请严格按要求输出,不要画蛇添足地打印类似:“请您输入...” 的多余内容。
 
所有代码放在同一个源文件中,调试通过后,拷贝提交该源码。
不要使用package语句。不要使用jdk1.7及以上版本的特性。
主类的名字必须是:Main,否则按无效代码处理。
import java.util.Scanner;

public class N_GlobalWarming {
    
    

	public static int[][][] world;
	public static int[][][] new_world;
	public static int N;
	
	public static boolean DFS(int i, int j) {
    
    
		boolean flag = true;
		if(new_world[i][j][0] == 1)
			flag = false;
		
		world[i][j][0] = 1;
		
		for(int o = -1; o < 2; o ++) {
    
    
			for(int p = -1; p < 2; p ++) {
    
    
				if(Math.abs(o + p) != 1)
					continue;
				if(i + o < 1 || i + o > N || j + p < 1 || j + p > N || world[i + o][j + p][0] == 1)
					continue;
				flag = DFS(i + o, j + p) || flag;	
			}
		}
		
		return flag;
	}
	
	public static void main(String[] args) {
    
    
		
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		sc.nextLine();
		world = new int[N + 2][N + 2][1];
		new_world = new int[N + 2][N + 2][1];
		
		for(int i = 0; i < N; i ++) {
    
    
				String temporary = sc.nextLine();
				for(int j = 0; j < N; j ++) {
    
    
					if(temporary.charAt(j) == '.') {
    
    
						world[i + 1][j + 1][0] = 1;
						new_world[i + 1][j + 1][0] = 1;
					}
				}
		}
		
//		0表示陆地     	1表示海洋		2表示陆转海	
		for(int i = 1; i <= N; i ++) {
    
    
			for(int j = 1; j <= N; j ++) {
    
    
				if(world[i][j][0] == 0)
					if(world[i][j - 1][0] == 1 || world[i][j + 1][0] == 1 || world[i - 1][j][0] == 1 || world[i + 1][j][0] == 1)
						new_world[i][j][0] = 1;
			}
		}
		
		int sum = 0;
		for(int i = 1; i <= N; i ++) {
    
    
			for(int j = 1; j <= N; j ++) {
    
    
				if(world[i][j][0] == 0)
					if(!DFS(i, j))
						sum ++;
			}
		}
		System.out.println(sum);
	}
}

2.“迷宫求解”

此题在做

  • List item

迷宫求解

【问题描述】
下图给出了一个迷宫的平面图,其中标记为 1 的为障碍,标记为 0 的为可
以通行的地方。
010000
000100
001001
110000
迷宫的入口为左上角,出口为右下角,在迷宫中,只能从一个位置走到这
个它的上、下、左、右四个方向之一。
对于上面的迷宫,从入口开始,可以按DRRURRDDDR 的顺序通过迷宫,
一共 10 步。其中 D、U、L、R 分别表示向下、向上、向左、向右走。
对于下面这个更复杂的迷宫(3050 列),请找出一种通过迷宫的方式,
其使用的步数最少,在步数最少的前提下,请找出字典序最小的一个作为答案。
请注意在字典序中D<L<R<U。(如果你把以下文字复制到文本文件中,请务
必检查复制的内容是否与文档中的一致)
01010101001011001001010110010110100100001000101010
00001000100000101010010000100000001001100110100101
01111011010010001000001101001011100011000000010000
01000000001010100011010000101000001010101011001011
00011111000000101000010010100010100000101100000000
11001000110101000010101100011010011010101011110111
00011011010101001001001010000001000101001110000000
10100000101000100110101010111110011000010000111010
00111000001010100001100010000001000101001100001001
11000110100001110010001001010101010101010001101000
00010000100100000101001010101110100010101010000101
11100100101001001000010000010101010100100100010100
00000010000000101011001111010001100000101010100011
10101010011100001000011000010110011110110100001000
10101010100001101010100101000010100000111011101001
10000000101100010000101100101101001011100000000100
10101001000000010100100001000100000100011110101001
00101001010101101001010100011010101101110000110101
11001010000100001100000010100101000001000111000010
00001000110000110101101000000100101001001000011101
10100101000101000000001110110010110101101010100001
00101000010000110101010000100010001001000100010101
10100001000110010001000010101001010101011111010010
00000100101000000110010100101001000001000000000010
11010000001001110111001001000011101001011011101000
00000110100010001000100000001000011101000000110011
10101000101000100010001111100010101001010000001000
10000010100101001010110000000100101010001011101000
00111100001000010000000110111000000001000000001011
10000001100111010111010001000110111010101101111000
【答案提交】
这是一道结果填空的题,你只需要算出结果后提交即可。本题的结果为一
个字符串,包含四种字母 D、U、L、R,在提交答案时只填写这个字符串,填
写多余的内容将无法得分。

猜你喜欢

转载自blog.csdn.net/qq_45696377/article/details/108425273