蓝桥杯总结与练习(一)模拟与高精度(包括日期相关算法)

(一)模拟与高精度

  想必大家都听说过“数学建模”这个东西,模拟其实也不难,相当于“计算机建模”,就是用计算机代码去模拟一些事件或规律,而这些规律题目已经直接过着间接得告诉你了,我们通常通过for循环和if判断就可以把事件或规律模拟出来了。
  根据规律,我大致分类以下三类问题:(1)简单模拟问题 。(2)高精度计算问题。(3)日期模拟问题


(1)简单模拟问题

  这类问题呢,也很简单,题目怎么 “说”,我们就怎么做,注意 “说”,可能题目不会直接告诉你规律,你可能需要观察输出来找到题目所 “说” 的规律。
  这一类题目没有固定的模板,所以先通过两个例子来看一下通常是怎么解决这些问题的。

龟兔赛跑预测(左键传送门)

题目描述

话说这个世界上有各种各样的兔子和乌龟,但是 研究发现,所有的兔子和乌龟都有一个共同的特点——喜欢赛跑。于是世界上各个角落都不断在发生着乌龟和兔子的比赛,小华对此很感兴趣,于是决定研究不同兔 子和乌龟的赛跑。他发现,兔子虽然跑比乌龟快,但它们有众所周知的毛病——骄傲且懒惰,于是在与乌龟的比赛中,一旦任一秒结束后兔子发现自己领先t米或以 上,它们就会停下来休息s秒。对于不同的兔子,t,s的数值是不同的,但是所有的乌龟却是一致——它们不到终点决不停止。
然而有些比赛相当漫长,全程观看会耗费大量时间,而小华发现只要在每场比赛开始后记录下兔子和乌龟的数据——兔子的速度v1(表示每秒兔子能跑v1 米),乌龟的速度v2,以及兔子对应的t,s值,以及赛道的长度l——就能预测出比赛的结果。但是小华很懒,不想通过手工计算推测出比赛的结果,于是他找 到了你——清华大学计算机系的高才生——请求帮助,请你写一个程序,对于输入的一场比赛的数据v1,v2,t,s,l,预测该场比赛的结果。

输入

输入只有一行,包含用空格隔开的五个正整数v1,v2,t,s,l,其中(v1,v2< =100;t< =300;s< =10;l< =10000且为v1,v2的公倍数)
输出
输出包含两行,第一行输出比赛结果——一个大写字母“T”或“R”或“D”,分别表示乌龟获胜,兔子获胜,或者两者同时到达终点。
第二行输出一个正整数,表示获胜者(或者双方同时)到达终点所耗费的时间(秒数)。

样例输入

10 5 5 2 20

样例输出

D
4

题目分析:

通过时间流动来模拟事件的进行,有几个注意点:
1.时间要一秒一秒的流动,如果通过跳动来模拟兔子睡觉的过程,会出现错误。
2.兔子进入睡眠状态的判断,和醒来的判断。

AC代码:
package Algorithm;

import java.util.Scanner;

/**
 * Created by IntelliJ IDEA.
 * User: ShiYu Huang
 * Date: 2021/1/31
 */
public class Day07TortoiseAndTheHare {
   
    public static void main(String[] args) {
   
        Scanner sc = new Scanner(System.in);
        //读取参数数据
        int v1 = sc.nextInt();
        int v2 = sc.nextInt();
        int t = sc.nextInt();
        int sleep = sc.nextInt();
        int l = sc.nextInt();
        //设定初始时间time,兔子初始路程s1,乌龟初始路程s2
        //兔子睡了几分钟sleep_flag,兔子是否处于睡觉状态
        int time = 0, s1 = 0, s2 = 0, sleep_flag = 0, sleep_trun = 0;
        
        while (s1 < l && s2 < l) {
   
            time++;//时间流动
            s2 += v2;//乌龟无论何时都往前进
            if (sleep_trun == 0) {
   //兔子没有睡觉就继续跑,否则睡一分钟
                s1 += v1;
            } else {
   
                sleep_flag++;
                if (sleep_flag == sleep) {
   //兔子醒来
                    sleep_trun = 0;
                }
            }
            if (s1 - s2 >= t && sleep_trun == 0) {
   //如果兔子是醒的且超过了乌龟,就要睡觉
                sleep_trun = 1;
                sleep_flag = 0;
            }
        }
        if (s1 > s2) {
   
            System.out.println("R");
        } else if (s1 == s2) {
   
            System.out.println("D");
        } else {
   
            System.out.println("T");
        }
        System.out.println(time);
    }
}


扫雷游戏(左键传送门)

题目描述

扫雷游戏是一款十分经典的单机小游戏。在nn行mm列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。
现在给出nn行mm列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。
注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

输入格式

第一行是用一个空格隔开的两个整数nn和mm,分别表示雷区的行数和列数。
接下来nn行,每行mm个字符,描述了雷区中的地雷分布情况。字符’*’表示相应格子是地雷格,字符’?’表示相应格子是非地雷格。相邻字符之间无分隔符。

输出格式

输出文件包含nn行,每行mm个字符,描述整个雷区。用’*’表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。

输入输出样例
输入 #1

3 3
*??
???
?*?

输出 #1

*10
221
1*1

输入 #2

2 3
?*?
*??

输出 #2

2*1
*21

说明/提示

对于 100%100%的数据, 1≤n≤100, 1≤m≤1001≤n≤100,1≤m≤100。

题目分析:

用二位数组将读取的矩阵存储起来,一个一个遍历,读到 * 跳过,读到 ? 就开始统计,统计当前位置的个方位藏雷的数量,注意:需要判断是否越界。

AC代码:
package 洛谷.模拟与高精度;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

public class P2670 {
   
	public static void main(String[] args) throws IOException {
   
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		String[] input = in.readLine().split(" ");
		int n = Integer.parseInt(input[0]), m = Integer.parseInt(input[1]);
		char[][] map = new char[n][m];
   		//读入给出的矩阵
		for (int i = 0; i < n; i++) {
   
			String s = in.readLine();
			for (int j = 0; j < m; j++) {
   
				map[i][j] = s.charAt(j);
			}
		}
		
		//遍历并进行统计
		for (int i = 0; i < n; i++) {
   
			for (int j = 0; j < m; j++) {
   
			    //统计到*跳过
				if (map[i][j] == '*') {
   
					continue;
				}
				int cnt = 0;//统计的数目
				
				//以下第一个条件判断是否越界,第二个条件判断有否是雷
				if (i - 1 >= 0) {
   //北
					if (map[i - 1][j] == '*') {
   
						cnt++;
					}
				}
				if (i - 1 >= 0 && j + 1 < m) {
   //东北
					if (map[i - 1][j + 1] == '*') {
   
						cnt++;
					}
				}
				if (j + 1 < m) {
   //东
					if (map[i][j + 1] == '*') {
   
						cnt++;
					}
				}
				if (i + 1 < n && j + 1 < m) {
   //东南
					if (map[i + 1][j + 1] == '*') {
   
						cnt++;
					}
				}
				if (i + 1 < n) {
   //南
					if (map[i + 1][j] == '*') {
   
						cnt++;
					}
				}
				if (i + 1 < n && j - 1 >= 0) {
   //西南
					if (map[i + 1][j - 1] == '*') {
   
						cnt++;
					}
				}
				if (j - 1 >= 0) {
   //西
					if (map[i][j - 1] == '*') {
   
						cnt++;
					}
				}
				if (i - 1 >= 0 && j - 1 >= 0
  • 7
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值