最高分是多少

本文探讨了如何使用Java实现老师查询学生最高分的问题,通过比较暴力法与线段树的数据结构,展示了线段树在查询效率上的优势。通过实例展示了如何用代码模拟老师的询问过程,以及如何使用线段树进行快速更新和查询操作。
摘要由CSDN通过智能技术生成

(java实现)


题目描述:

老师想知道从某某同学当中,分数最高的是多少,现在请你编程模拟老师的询问。当然,老师有时候需要更新某位同学的成绩.

输入描述:

输入包括多组测试数据。
每组输入第一行是两个正整数N和M(0 < N <= 30000,0 < M < 5000),分别代表学生的数目和操作的数目。
学生ID编号从1编到N。
第二行包含N个整数,代表这N个学生的初始成绩,其中第i个数代表ID为i的学生的成绩
接下来又M行,每一行有一个字符C(只取‘Q’或‘U’),和两个正整数A,B,当C为’Q’的时候, 表示这是一条询问操作,他询问ID从A到B(包括A,B)的学生当中,成绩最高的是多少
当C为‘U’的时候,表示这是一条更新操作,要求把ID为A的学生的成绩更改为B。

输出描述:

对于每一次询问操作,在一行里面输出最高成绩.

示例1:

输入

5 7
1 2 3 4 5
Q 1 5
U 3 6
Q 3 4
Q 4 5
U 4 5
U 2 9
Q 1 5

输出

5
6
5
9


问题分析:

思路一:暴力法。每次查询直接做。
修改复杂度O(1),查询复杂度O(N)
思路二:使用线段树。线段树这种数据结构,修改O(logn),查询O(logn),但是要预处理O(nlogn)

相关知识:

参考代码:

思路一实现:

import java.util.*;
public class Main {
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        while (input.hasNext())
        {
            String[] str = input.nextLine().split(" ");
            int n = Integer.parseInt(str[0]);
            int m = Integer.parseInt(str[1]);
            int[] arr = new int[n+1];
            str = input.nextLine().split(" ");
            for (int i=1; i<=n; i++)
            {
                arr[i] = Integer.parseInt(str[i-1]);
            }
            for (int i=0; i<m; i++)
            {
                str = input.nextLine().split(" ");
                int index = Integer.parseInt(str[1]);
                int value = Integer.parseInt(str[2]);
                if (str[0].equals("Q"))
                {
                    System.out.println(getMax(arr,index,value));
                }else if (str[0].equals("U"))
                {
                    arr[index] = value;
                }
            }
        }
    }
    public static int getMax(int[] arr, int a, int b)
    {
        int max = Integer.MIN_VALUE;
        // a不一定是最小的
        if (a > b)
        {
            int tmp = a;
            a = b;
            b = tmp;
        }
        for (int i=a; i<=b; i++)
        {
            if (max < arr[i])
                max = arr[i];
        }
        return max;
    }
}

思路一实现:(不使用nextLine());

import java.util.Scanner;
public class Main {

	 public static void main(String[] args)throws Exception{
		Scanner s = new Scanner(System.in);
		while(s.hasNext())
        {
		    int n = s.nextInt();
		    int m = s.nextInt();
		    int[] arr = new int[n];
		    for(int i = 0; i <n; i ++)
            {
			    arr[i] = s.nextInt();
            }
		    int count = 0;
		    char a ;
		    int b,c;
		    while(count < m)
            {
			    a = s.next().charAt(0);
			    b = s.nextInt();
			    c = s.nextInt();
			    if('Q' == a)
                {
				    int start, end;
				    if(b <= c)
                    {
				        start = b - 1;
				        end = c - 1;
				    }else{
					    start = c - 1;
					    end = b - 1;
				    }
				    int max = arr[start];
				    for(int index=start; index<=end; index++)
                    {
					    if(arr[index] > max)
						    max = arr[index];
				    }
				    System.out.println(max);
			    }
			    if('U' == a){
				    int index1 = b - 1;
				    int newValue = c;
                    arr[index1] = newValue;
			    }
			    s.nextLine();
			    count++;
		    }
		 }
		 s.close();
	}
}

思路二实现:

import java.util.Scanner;
public class Main {
    public static int MAXN=100000;
    public static int[] data = new int[MAXN+5];
    public static int[] maxarr = new int[MAXN*4+5];
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        while (input.hasNext())
        {
            String[] str = input.nextLine().split(" ");
            int n = Integer.parseInt(str[0]);
            int m = Integer.parseInt(str[1]);
            /*
            int n = input.nextInt();
            int m = input.nextInt();
            */
            str = input.nextLine().split(" ");
            for (int i=1; i<=n; i++)
            {
                data[i] = Integer.parseInt(str[i-1]);
            }
            /*
            for (int i=1; i<=n; i++)
            {
                data[i] = input.nextInt();
            }*/
            build(1, 1, n);
            char order;
            int a=0, b=0;
            for (int i=0; i<m; i++)
            {
                str = input.nextLine().split(" ");
                order = str[0].charAt(0);
                a = Integer.parseInt(str[1]);
                b = Integer.parseInt(str[2]);
                /*
                order = input.next().charAt(0);
                a = input.nextInt();
                b = input.nextInt();
                */
                if ('U' == order)
                {
                    update(a,b,1,1,n);
                }else if ('Q' == order)
                {
                    if (a>b)
                    {
                        int tmp = a;
                        a = b;
                        b = tmp;
                    }
                    System.out.println(querymax(a,b,1,1,n));
                }
                //input.nextLine();
            }
            
        }
    }
    
    public static void build(int p,int l,int r)
    {
        if (l == r)
        {
            maxarr[p] = data[l];
            return;
        }
        int m = (l+r)>>1;
        int lchild = p<<1, rchild = p<<1|1;
        build(lchild, l, m);
        build(rchild, m+1, r);
        maxarr[p] = Math.max(maxarr[lchild], maxarr[rchild]);
    }
    public static void update(int idx, int value, int p, int l, int r)
    {
        if (l==r && l==idx)
        {
            maxarr[p] = value;
            return;
        }
        int m = (l+r)>>1;
        if (idx <= m)
            update(idx, value, p<<1, l, m);
        if (m < idx)
            update(idx, value, p<<1|1, m+1, r);
        maxarr[p] = Math.max(maxarr[p<<1], maxarr[p<<1|1]);
    }
    public static int querymax(int L, int R, int p, int l, int r)
    {
        if (L<=l && r<=R)
            return maxarr[p];
        int m = (l+r)>>1;
        int lans=-1,rans=-1;
        if (L<=m)
            lans = querymax(L,R,p<<1,l,m);
        if (m < R)
            rans = querymax(L,R,p<<1|1,m+1,r);
        if (lans==-1)
            return rans;
        if (rans==-1)
            return lans;
        return Math.max(lans,rans);
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值