21年蓝桥杯省赛题目 JAVA C组(二)

目录

#F 时间显示

#G 最少砝码

#H 杨辉三角形

#I 左孩子右兄弟

#J 双向排序


#F 时间显示

时间限制: 1.0s 内存限制: 512.0MB 本题总分:15  分

问题描述

  小蓝要和朋友合作开发一个时间显示的网站。在服务器上,朋友已经获取了当前的时间,用一个整数表示,值为从 1970 年 1  月 1 日 00 : 00 : 00 到当前时刻经过的毫秒数。

  现在,小蓝要在客户端显示出这个时间。小蓝不用显示出年月日,只需显示出时分秒即可,毫秒也不用显示,直接舍去即可。

  给定一个用整数表示的时间,请将这个时间对应的时分秒输出。

输入格式

  输入一行包含一个整数,表示时间。

输出格式

  输出时分秒表示的当前时间,格式形如 H H :M M :S S ,其中 H H  表示时,值为 0到 23 ,M M 表示分,值为 0  到 59 ,S S 表示秒,值为 0  到 59 。时、分、秒不足两位时补前导 0 。

import java.util.Scanner;

public class questionF {
// #F 时间显示
	public static void main(String[] args) {
		// 根据毫秒换算时分秒
		Scanner sc=new Scanner(System.in);
		long t = sc.nextLong();
        System.out.printf("%02d:%02d:%02d",t/3600000%24,t/60000%60,t/1000%60);
	}

}

#G 最少砝码

时间限制: 1.0s 内存限制: 512.0MB 本题总分:20 分

问题描述

  你有一架天平。现在你要设计一套砝码,使得利用这些砝码可以称出任意小于等于 N  的正整数重量。

  那么这套砝码最少需要包含多少个砝码?

  注意砝码可以放在天平两边。

输入格式

  输入包含一个正整数 N 。

输出格式

  输出一个整数代表答案。

import java.util.Scanner;

public class questionG {
// #G 最少砝码
	public static void main(String[] args) {
		// 根据规律来找到其中的解法
		Scanner sc=new Scanner(System.in);
		long x=sc.nextLong();
		long sum=1,cur=1;
		while(sum<x){
			sum+=Math.pow(3, cur);
			cur++;
		}
		System.out.println(cur);
	}

}

#H 杨辉三角形

时间限制: 5.0s 内存限制: 512.0MB 本题总分:20 分

  下面的图形是著名的杨辉三角形:

  如果我们按从上到下、从左到右的顺序把所有数排成一列,可以得到如下数列:

 1, 1, 1, 1, 2, 1, 1, 3, 3, 1, 1, 4, 6, 4, 1, …

  给定一个正整数 N ,请你输出数列中第一次出现 N 是在第几个数?

输入格式

  输入一个整数 N 。

输出格式

  输出一个整数代表答案。

import java.util.Scanner;

public class questionH {
 // #H 杨辉三角形
	static int N;
	public static void main(String[] args) {
		// 根据每层的规律来找出其中的解法
		Scanner sc=new Scanner(System.in);
		N = new Scanner(System.in).nextInt();
        if (N == 1) System.out.println(1);
        else {
            long ans = (N + 1L) * N / 2 + 2;
            for (int m = 2; m < 16; m++) {
                int start = m * 2, end = N;
                while (start <= end) {
                    int mid = start + end >> 1;
                    if (C(mid, m) == N) {
                        ans = min(ans, (mid + 1L) * mid / 2 + m + 1);
                        break;
                    } if (C(mid, m) > N) end = mid - 1;
                    else start = mid + 1;
                }
            }
            System.out.println(ans);
        }
	}
	public static long min(long a, long b) { 
		return a < b ? a : b; 
		}

    public static long C(int n, int m) {
        long num = 1;
        for (int nm = 1; nm <= m; n--, nm++)
            if ((num = num * n / nm) > N) return num;
        return num;
    }

}

#I 左孩子右兄弟

时间限制: 2.0 s 内存限制: 512.0MB 本题总分:25 分

问题描述

  对于一棵多叉树,我们可以通过 “左孩子右兄弟” 表示法,将其转化成一棵二叉树。

  如果我们认为每个结点的子结点是无序的,那么得到的二叉树可能不唯一。换句话说,每个结点可以选任意子结点作为左孩子,并按任意顺序连接右兄弟。

  给定一棵包含 N 个结点的多叉树,结点从 1 至 N 编号,其中 1 号结点是根,每个结点的父结点的编号比自己的编号小。请你计算其通过 “左孩子右兄弟” 表示法转化成的二叉树,高度最高是多少。注:只有根结点这一个结点的树高度为 0 。

  例如如下的多叉树:

  可能有以下 3 种 (这里只列出 3 种,并不是全部) 不同的 “左孩子右兄弟”表示:

  其中最后一种高度最高,为 4 。

输入格式

  输入的第一行包含一个整数 N 。

  以下 N − 1 行,每行包含一个整数,依次表示 2 至 N 号结点的父结点编号。

输出格式

  输出一个整数表示答案。

 

import java.io.*;
import java.util.*;
public class questionI {
//#I 左孩子右兄弟
	public static List<Integer>[] tree;
	public static void main(String[] args) {
		// 依据题目得出状态转移方程:
		// dp(v)=count(son(v))+max{dp(son(v))}
		Scanner in = new Scanner(System.in);
        int n = in.nextInt(), v;
        tree = new List[n + 1];
        for (int w = 2; w <= n; w++) {
            v = in.nextInt();
            if (tree[v] == null)
                tree[v] = new ArrayList();
            tree[v].add(w);
        }
        System.out.println(dp(1));
	}
	public static int dp(int v) {
        if (tree[v] == null) return 0;
        int max = 0;
        for (int w : tree[v])
            max = Math.max(max, dp(w));
        return tree[v].size() +  max;
    }

	public class InputReader {

        BufferedReader reader;
        StringTokenizer token;

        public  InputReader(InputStream in) {
            this.reader = new BufferedReader(new InputStreamReader(in));
        }

        public  String read() {
            while (token == null || !token.hasMoreTokens()) {
                try {
                    token = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return token.nextToken();
        }

        public int readInt() { 
        	return Integer.parseInt(read()); 
        	}
    }
}

#J 双向排序

时间限制: 5.0 s 内存限制: 512.0 MB 本题总分:25 分

问题描述

  给定序列 ( a 1 , a 2 , …… , a n ) = ( 1 , 2 , …… , n ) ,即 a i = i 。

  小蓝将对这个序列进行 m 次操作,每次可能是将 a 1 , a 2 , …… , a qi 降序排列,或者将 a qi , a qi + 1 , …… , a n 升序排列。

  请求出操作完成后的序列。

输入格式

  输入的第一行包含两个整数 n , m ,分别表示序列的长度和操作次数。

  接下来 m 行描述对序列的操作,其中第 i 行包含两个整数 p i , q i 表示操作类型和参数。当 p i = 0 时,表示将a 1 , a 2 , …… , a qi 降序排列;当 p i = 1 时,表示将 a qi , a qi + 1 , …… , a n 升序排列。

输出格式

  输出一行,包含 n 个整数,相邻的整数之间使用一个空格分隔,表示操作完成后的序列。

 

import java.io.*;
import java.util.*;
public class questionJ {
//	#J 双向排序
	public static void main(String[] args) {
		// 对于连续且 pi相同操作
		//在 pi=0 时只需要做 qi最大的操作
		//在 pi=1时只需要做 qi最小的操作
		InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = in.readInt(), m = in.readInt();
        Deque<Step> deque = new ArrayDeque();
        deque.push(new Step(1, 1));
        while (m-- > 0) {
            int p = in.readInt();
            int q = in.readInt();
            while (deque.size() > 0 && deque.peek().p == p)
                if (p == 0)
                    q = max(q, deque.pop().q);
                else
                    q = min(q, deque.pop().q);
            deque.push(new Step(p, q));
	}
    Integer[] ans = new Integer[n];
    for (int i = 0; i < n; i++)
        ans[i] = i + 1;
    deque.pollLast();
    while (deque.size() > 0) {
        Step step = deque.pollLast();
        if (step.p == 0)
            Arrays.sort(ans, 0, step.q, (a, b)->(b - a));
        else
            Arrays.sort(ans, step.q - 1, n);
    }
    for (int i = 0; i < n; i++) {
        out.print(ans[i]);
        out.print(' ');
    }
    out.flush();
}
	public static int max(int a, int b) { 
		return a > b ? a : b; 
		}

	public static int min(int a, int b) { 
		return a < b ? a : b; 
		}

	public static class Step {

    	public  int p, q;

    	public  Step(int p, int q) {
            this.p = p;
            this.q = q;
        }
    }

	public static class InputReader {

        BufferedReader reader;
        StringTokenizer token;

        public  InputReader(InputStream in) {
            this.reader = new BufferedReader(new InputStreamReader(in));
        }

        public  String read() {
            while (token == null || !token.hasMoreTokens()) {
                try {
                    token = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return token.nextToken();
        }

        public  int readInt() { 
        	return Integer.parseInt(read()); 
        	}
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值