蓝桥杯真题3

[蓝桥杯 2015 省 B] 移动距离

题目描述

X 星球居民小区的楼房全是一样的,并且按矩阵样式排列。其楼房的编号为 $1,2,3, \cdots $ 。

当排满一行时,从下一行相邻的楼往反方向排号。

比如:当小区排号宽度为 6 6 6 时,开始情形如下:

1  2  3  4  5  6
12 11 10 9  8  7
13 14 15 .....

我们的问题是:已知了两个楼号 m m m n n n,需要求出它们之间的最短移动距离。(不能斜线方向移动)

输入格式

输入为 3 3 3 个整数 wmn,空格分开,都在 1 1 1 10000 10000 10000 范围内。

w w w 为排号宽度, m , n m,n m,n 为待计算的楼号。

输出格式

要求输出一个整数,表示 m m m n n n 两楼间最短移动距离。

样例 #1

样例输入 #1

6 8 2

样例输出 #1

4

样例 #2

样例输入 #2

4 7 20

样例输出 #2

5

提示

时限 1 秒, 256M。

蓝桥杯 2015 年省赛 B 组 H 题。

分析

这道题有点类似于高中数学学的二维坐标系的距离问题,即哈密顿距离 |x1-x2|+|y1-y1|,因此我们只需要知道所求两个点的横纵坐标既可以求出最短距离。x = n/W,y = n % w;关键就在于他的列号排列不像正常的坐标系去从左向右排列,而是蛇形排列的。我们不妨把这个楼层的行列也设为数组的行列排序,即从0开始,我们发现只要是奇数行即(n%w == 1)的行,他的列号是要颠倒的,如何实现颠倒列号呢,很简单 y = w - 1 - n % w;就是高中时学的数轴找对称点。

代码实现

import java.util.*;
public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int w = scan.nextInt();
        int m = scan.nextInt();
        int n = scan.nextInt();
        m--;n--;//将其转化为数组下标也即是从0开始。
        int x1 = m / w,x2 = n / w;
        int y1 = m % w,y2 = n % w;
        if(x1 % 2 == 1) y1 = w - 1 - m % w;
        if(x2 % 2 == 1) y2 = w - 1 - n % w;
        System.out.println(Math.abs(x1-x2)+Math.abs(y1-y2));
    }
}

[蓝桥杯 2017 省 B] 日期问题

题目描述

小明正在整理一批历史文献。这些历史文献中出现了很多日期。小明知道这些日期都在 1960 年 1 月 1 日至 2059 年 12 月 31 日。令小明头疼的是,这些日期采用的格式非常不统一,有采用年/月/日的,有采用月/日/年的,还有采用日/月/年的。更加麻烦的是,年份也都省略了前两位,使得文献上的一个日期,存在很多可能的日期与其对应。

比如 02/03/04,可能是 2002 年 03 月 04 日、2004 年 02 月 03 日或 2004 年 03 月 02 日。

给出一个文献上的日期,你能帮助小明判断有哪些可能的日期对其对应吗?

输入格式

一个日期,格式是 AA/BB/CC。( 0 ≤ A , B , C ≤ 9 0\le A, B, C\le 9 0A,B,C9)

输出格式

输出若干个不相同的日期,每个日期一行,格式是 yyyy-MM-dd。多个日期按从早到晚排列。

样例 #1

样例输入 #1

02/03/04

样例输出 #1

2002-03-04  
2004-02-03  
2004-03-02

分析

本来我看这道题的思路是,枚举三种位置组成的所有日期,然后再去检验是否合法,但当真正去写的时候发现有个很大的问题,太过繁琐麻烦,你不仅需要去判断是19··年还是20··年,还有闰年什么的情况,再加上判断日子等等,最后还需要排序输出。所以我们换一种思路,枚举所有960 年 1 月 1 日至 2059 年 12 月 31 日之间的日子,判断日期是否合法,同时判断这个日期是否可以由三种构成方法中的任一种组成,这样无疑会简单许多。

代码实现

import java.util.*;
public class Main{
    static int[] Months = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        String date = scan.next();
        String[] s = date.split("/");
        int a = Integer.parseInt(s[0]);
        int b = Integer.parseInt(s[1]);
        int c = Integer.parseInt(s[2]);
        for(int i = 19600101;i <= 20591231;i++){
        int y = i / 10000;
        int m = i % 10000 / 100;
        int d = i % 100;
            if(checkYear(i)){
                if(y % 100 == a && m==b && d ==c||
                y % 100 == c && m == b && d == a||
                y % 100 == c&&  m == a && d == b){
                    System.out.print(y+"-");
                    if(m<10)System.out.print("0");
                    System.out.print(m+"-");
                    if(d<10)System.out.print("0");
                    System.out.println(d);
                }
            }
        }
    }
    public static boolean checkYear(int i){
        int y = i / 10000;
        int m = i % 10000 / 100;
        int d = i % 100;
        if(m == 0 || m > 12) return false;
        if(d == 0) return false;
        if(m != 2){
            if(d > Months[m]) return false;
        }else{
            int leap = 0;
            if(y % 100 != 0 && y % 4 == 0 || y % 400 == 0){
                leap = 1;
            }
            if(d > Months[2]+leap){
                return false;
            }
        }
        return true;
    }
}

早先思路代码实现

import java.io.*;
import java.util.TreeSet;

public class Main {
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static TreeSet<String> ans = new TreeSet<>();
    static int []normalYear = {0,31,28,31,30,31,30,31,31,30,31,30,31};
    static int []leapYear = {0,31,29,31,30,31,30,31,31,30,31,30,31};
    static String []num = {"19","20"};
    static String maxDate = "2059-12-31",minDate = "1960-01-01";

    static boolean isLeapYear(String year){
        int numYear = Integer.parseInt(year);
        return numYear % 4 == 0 && numYear % 100 != 0 || numYear % 400 == 0;
    }

    static void add(String a,String b,String c){
        String res;
        int month = Integer.parseInt(b);
        if (month == 0 || month > 12)return;
        int maxDay;
        if (isLeapYear(a))maxDay = leapYear[month];
        else maxDay = normalYear[month];
        int day = Integer.parseInt(c);
        if (day == 0 || day > maxDay)return;
        res = a + "-" + b + "-" + c;
        if (res.compareTo(maxDate) <= 0 && res.compareTo(minDate) >= 0)ans.add(res);
    }

    public static void main(String[] args) throws IOException {
        String []all = br.readLine().split("/");
        for(int i = 0 ; i < 2 ; i ++){
            add(num[i] + all[0],all[1],all[2]);
            add(num[i] + all[2],all[0],all[1]);
            add(num[i] + all[2],all[1],all[0]);
        }
        for(String i :ans) System.out.println(i);
    }
}

你可能感兴趣的:(算法,蓝桥杯,算法,java)